package org.seqcode.projects.seqview;
import java.util.*;
import java.io.*;
import java.net.URL;
import javax.swing.*;
import org.seqcode.gseutils.json.*;
import org.seqcode.gseutils.models.*;
import org.seqcode.projects.seqview.components.MultiModelPrefs;
import org.seqcode.projects.seqview.components.RegionPanel;
import org.seqcode.viz.components.RegexFileFilter;
/** Base class for SeqView (paintable and model) properties.
* Uses Tim's JSON model stuff to handle serializing and deserializing.
*/
public abstract class SeqViewProperties extends Model {
// controls whether some exception stack traces are printed
private boolean debugging = true;
/* true when a window is currently open to configure this SeqViewProperties.
Used to prevent multiple windows from working on the same properties at once.
*/
private Boolean configuring;
public SeqViewProperties() {
super();
configuring = Boolean.FALSE;
}
static class DoneConfiguring implements Runnable {
private Collection<SeqViewProperties> p;
private MultiModelPrefs mmp;
public DoneConfiguring(Collection<SeqViewProperties> p, MultiModelPrefs mmp ) {this.p = p;this.mmp = mmp;}
public void run() {
synchronized (mmp) {
boolean done = false;
while (!done) {
try {
mmp.wait();
for (SeqViewProperties prop : p) {
prop.configuring = false;
}
done = true;
} catch (InterruptedException e) {
// ignore it and go back to sleeping
}
}
}
}
}
public static void configure(Collection<? extends SeqViewProperties> props, RegionPanel regionpanel, boolean batchUpdate) {
Collection<SeqViewProperties> touse = new ArrayList<SeqViewProperties>();
for (SeqViewProperties p : props) {
synchronized(p) {
if (p.configuring) {
continue;
}
p.configuring = true;
}
touse.add(p);
}
MultiModelPrefs frame = new MultiModelPrefs(touse,regionpanel, batchUpdate);
(new Thread(new DoneConfiguring(touse,frame))).start();
frame.setSize(frame.getPreferredSize());
frame.setVisible(true);
frame.pack();
frame.setLocationRelativeTo(null);
}
/**
* Since both PaintableProperties and ModelProperties inherit from here, we don't want to
* confuse the two types of properties. So each subclass needs to define the suffix that its
* files use.
*/
public abstract String fileSuffix();
public String defaultName() {
return getClass().toString().replaceAll("^.*\\.","") + ".defaults." + fileSuffix();
}
public File currentFile() {
return new File(System.getProperty("user.dir") + System.getProperty("file.separator") + defaultName());
}
public File defaultFile() {
return new File(System.getProperty("user.home") + System.getProperty("file.separator") + defaultName());
}
/** Displays a JFileChooser to select the name of the file to which you want to save the properties
*/
public void saveToFile() {
JFileChooser chooser = new JFileChooser();
RegexFileFilter filter = new RegexFileFilter(".*\\." + fileSuffix() + "$", "SeqView Prefs",true);
chooser.setFileFilter(filter);
chooser.setSelectedFile(defaultFile());
int returnVal = chooser.showSaveDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = chooser.getSelectedFile();
saveToFile(f);
}
}
/** Saves these properties to the specified file
*/
public void saveToFile(File f) {
JSONObject json = asJSON();
try {
PrintWriter pw = new PrintWriter(f);
pw.println(json.toString());
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/** Displays a JFileChooser to select the file from which you want to load the properties
*/
public void loadFromFile() {
JFileChooser chooser = new JFileChooser();
RegexFileFilter filter = new RegexFileFilter(".*\\." + fileSuffix() + "$", "SeqView Prefs",true);
chooser.setFileFilter(filter);
chooser.setSelectedFile(defaultFile());
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = chooser.getSelectedFile();
try {
loadFromFile(f);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/** Load these properties from the specified file
*/
public void loadFromFile(File f) throws FileNotFoundException {
loadFromStream(new FileReader(f));
}
public void loadFromStream(InputStreamReader reader) {
try {
BufferedReader breader = new BufferedReader(reader);
JSONObject json = new JSONObject(breader.readLine());
breader.close();
reader.close();
setFromJSON(json);
} catch (Exception e) {
e.printStackTrace();
}
}
/** Load default values for properties. This looks for a file of the form
* FOO.defaults.svpp (seq view paintable properties) where FOO is the runtime class name in
* - current directory
* - home directory
* - the whole classpath
*/
public void loadDefaults() {
File name = currentFile();
try {
if (name.exists()) {
loadFromFile(name);
} else {
name = defaultFile();
if (name.exists()) {
loadFromFile(name);
} else {
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL url = cl.getResource(defaultName());
if (url != null) {
loadFromStream(new InputStreamReader(url.openStream()));
}
}
}
} catch (Exception e) {
if (debugging) {
e.printStackTrace();
}
}
}
}