package jas2.swingstudio;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.lang.reflect.*;
import jas2.util.*;
import jas2.util.SplashScreen;
import jas2.util.xml.*;
import jas2.util.tree.*;
import jas2.util.layout.*;
import jas2.util.moverlayeredpane.MLPArrowFactory;
import jas2.util.moverlayeredpane.MLPLabelFactory;
import jas2.util.moverlayeredpane.MoverLayeredPane;
import jas2.util.multifunctionpanel.MultiFunctionPanel;
import jas2.util.xmlmenus.*;
import jas2.util.pluginmanager.*;
import jas2.plugin.*;
import jas2.loader.*;
import jas2.hist.*;
import jas2.jds.interfaces.*;
import jas2.jds.module.*;
//import jas2.hist.test.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileFilter;
public final class JavaAnalysisStudio extends Application
{
/**
*
*/
private static final long serialVersionUID = 1L;
private static int makeCount = 0;
private ClassPathLoader m_extensionLoader;
private CommandProcessor m_currentSelection;
private ExtensionPluginContext pluginContext;
private JASConsoleTabbedPane m_JASConsoleTabbedPane;
private WindowManager m_windowManager;
private JMenuBar m_disconnectedMenuBar;
private JASJob m_job = null;
private JTree m_tree;
private JASTopBottomSplitPane m_topBottomSplitPane;
private JASLeftRightSplitPane m_leftRightSplitPane;
private static JavaAnalysisStudio theApp;
private JASToolbarHolder m_toolbarHolder;
private JFrame frame;
private JTabbedPane m_controlPane;
private StatusBar m_status;
private boolean m_statusBarVisible;
private UserProperties userProp = getUserProperties();
private int nPages = 0;
private String[] m_lastJobs, m_lastFiles;
// lastFiles is the array of programs
private JASCommand m_jasCommand;
private JASStoppableManager m_stopMan = new JASStoppableManager();
private URL m_homePage;
private boolean m_noTopBottomSplitPane = true;
private String menuFile = "menus.xml";
private PluginManager pluginmanager;
final String m_lastJobPath_Key = "LastJobPath";
final static private String m_WindowsLAF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
final static private String m_MotifLAF = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
final static private String m_JavaLAF = "javax.swing.plaf.metal.MetalLookAndFeel";
final static private String m_TabbedWM = "jas2.swingstudio.JASWindowManager";
final static private String m_InternalWM = "jas2.swingstudio.InternalFramesWindowManager";
final static private String versionURL = "http://jas.freehep.org/version.asp";
final static boolean jobSavingDisabled = true;
static final long checkWord = 3457768635619245585L;
static
{
try
{
// check that java 3d and the plot3d routines are both available
Class.forName("javax.media.j3d.Canvas3D");
Class.forName("gov.fnal.plot3d.jas.SpecialLego");
Class.forName("gov.fnal.plot3d.jas.SpecialSurface");
if (JPopupMenu.getDefaultLightWeightPopupEnabled())
{
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
}
}
catch (Throwable t)
{
}
}
static final String[][] knownDebugFlags =
{
{ "loader", "Debug Class Loaders" },
{ "eventDelivery", "Remote Event Delivery" },
{ "caching", "Caching of Remote Data"},
{ "extensions", "Extension loading"},
{ "printing", "Printing"},
{ "help", "Help"},
{ "all", "Turn on all known debug flags"},
};
protected void doHelp()
{
System.out.println();
System.out.println(getVersionName());
System.out.println();
super.doHelp();
System.out.println();
System.out.println("Parameters:");
System.out.println("\tp1 - A job file to read at startup");
System.out.println();
System.out.println("Known debug flags:");
for (int i=0; i 0)
jobToLoad = m_lastJobs[0];
}
final String jobToOpen = jobToLoad;
final GetOptions gopt = getGetOptions();
//frame.setBounds(userProp.getRectangle("Window", new Rectangle(10,10,450,450)));
}
/*
public JFrame getFrame(){
return frame;
}
*/
String getUserExtensionsDir()
{
return resolveSymbols(System.getProperty("jas.user.extensions","{user.home}/JASExtensions"));
}
String getGroupExtensionsDir()
{
return resolveSymbols(System.getProperty("jas.group.extensions"));
}
String getSystemExtensionsDir()
{
return resolveSymbols(System.getProperty("jas.system.extensions","lib"+File.separator+"extensions"));
}
/**
* Show it
*/
public void showIt(boolean show){
frame.setVisible(show);
}
/**
* Close it
*/
public void close(){
m_lastJobs=null;
frame.setVisible(false);
frame.dispose();
}
public JASToolbarHolder getToolbar(){
return m_toolbarHolder;
}
/**
* Search the extensions directory for JAR files, and add them to the extensions
* CLASSPATH.
*/
private void loadExtensions()
{
boolean debugExtensions = System.getProperty("debugExtensions") != null;
ClassPath extensionClasspath = new ClassPath();
Vector plugins = new Vector();
Vector plugininfo = new Vector();
// We look for extensions:
// a) In the directory specified by the jas.user.extensions System property
// b) In the directory specified by the jas.group.extensions System property
// c) In the directory specified by the jas.system.extensions System property
// The following defaults apply if the property is not specified
// a) {user.home}/JASExtensions
// b) none
// c) {java.home}/JASExtensions
String[] extDirs =
{
getUserExtensionsDir(),
getGroupExtensionsDir(),
getSystemExtensionsDir()
};
scanExtensionDirectories(extDirs,extensionClasspath,plugins,plugininfo,debugExtensions);
// Create the extension Loader.
m_extensionLoader = new ClassPathLoader(extensionClasspath,"ExtensionLoader");
// Create a plugin context to pass to the plugins
pluginContext = new JASPluginContext(this);
// Now try loading the plugins
Enumeration e = plugins.elements();
Enumeration info = plugininfo.elements();
File file;
pluginmanager = new PluginManager(getSystemExtensionsDir(),getUserExtensionsDir());
while (e.hasMoreElements())
{
String name = (String) e.nextElement();
file = ((File) info.nextElement());
String infopath = file.getParent();
String infofile = file.getName();
try
{
System.out.println("Loading extension: "+name);
Class c = m_extensionLoader.loadClass(name,true);
IExtensionPlugin p = (IExtensionPlugin) c.newInstance();
p.setPluginContext(pluginContext);
if(p instanceof IPluginInfo){
pluginmanager.setPluginLoadedAtStart(((IPluginInfo) p).getName(),((IPluginInfo) p).getVersion(), infopath, infofile);
}else pluginmanager.setPluginLoadedAtStart(infofile,"unknown",infopath, infofile);
}
catch (Throwable t)
{
System.err.println("Unable to load plugin "+name);
t.printStackTrace();
}
}
}
public ExtensionPluginContext getPluginContext(){
return pluginContext;
}
private void scanExtensionDirectories(String[] dirs, ClassPath extensionClasspath, Vector plugins, Vector plugininfo,boolean debugExtensions)
{
for (int i=0; i 0) out.append(in.substring(0,start));
String prop = System.getProperty(in.substring(start+1,end-start));
if (prop != null) out.append(prop);
if (end + 1 < in.length()) out.append(in.substring(end+1));
in = out.toString();
}
return in;
}
private void scanExtensionDirectory(File extdir, ClassPath extensionClasspath, Vector plugins,Vector plugininfo,boolean debugExtensions)
{
String[] files = extdir.list();
for (int i=0; i 0){
try
{
//path = f.getParent();
ZipFile zipFile = new ZipFile(f);
ZipEntry manifest = zipFile.getEntry("JAS-inf/plugins.txt");
if (manifest != null )
{
// Each line of the manifest should contain the name of a Plugin class file
LineNumberReader reader = new LineNumberReader(new InputStreamReader(zipFile.getInputStream(manifest)));
for (;;)
{
String line = reader.readLine();
if (line == null) break;
if (plugins.indexOf(line) < 0)
{
plugins.addElement(line);
plugininfo.addElement(f);
}
}
reader.close();
}
if (debugExtensions) System.out.println("\tFound: "+files[i]);
extensionClasspath.add(zipFile);
}
catch (IOException x)
{
System.err.println("Extension jar file "+files[i]+" could not be loaded"+x);
}
}else{ // Files with length 0 have been flagged for deletion by the plugin manager.
boolean removed = f.delete();
}
}
}
}
private void reconnect(String connect) throws Exception
{
StringTokenizer t = new StringTokenizer(connect,"/");
if (t.countTokens() != 2) throw new ConnectException("Invalid connect option "+connect);
String node = t.nextToken();
String jobName = t.nextToken();
JavaDataServer jds = JASJobAdaptor.connectToServer(node,null,0,this);
if (jds == null) return;
JASJob jasJob = new JASJob(jobName);
JASJobAdaptor job = new JASJobAdaptor(jasJob,jobName,jds,this);
jasJob.setJob(job);
setJob(jasJob, true);
job.listItems();
}
public JASPage getCurrentPage()
{
try
{
Component c = m_windowManager.getWindow( m_windowManager.getSelectedWindow() );
return (JASPage) c;
}
catch (Exception e)
{
return null;
}
}
public JTabbedPane getControlPane()
{
return m_controlPane;
}
public JTabbedPane getConsolePane()
{
return m_JASConsoleTabbedPane;
}
public JASPage newPage(int nx, int ny)
{
nPages++;
JASPage page = new JASPage(nx,ny);
m_windowManager.newWindow("Page "+nPages,page);
return page;
}
public void setNPages(int nPages)
{
this.nPages = nPages;
}
public void setStatusBarVisible(boolean visible)
{
m_statusBarVisible = visible;
if (visible) add(BorderLayout.SOUTH,m_status);
else remove(m_status);
revalidate();
}
public JMenuBar getMenuBar()
{
return m_disconnectedMenuBar;
}
public JASJob getJob()
{
return m_job;
}
public ClassPathLoader getExtensionLoader()
{
return m_extensionLoader;
}
public static String getVersionNumber()
{
// Dont return anything but i.j.k here, or it messes up the plugin manager
return "2.2.8";
}
String getVersionName()
{
return "Java Analysis Studio - "+getVersionNumber()+" (10 April 2002)";
}
public static void main(String argv[])
{
try
{
theApp = new JavaAnalysisStudio();
}
catch (Throwable e)
{
System.err.println("Java Analysis Studio Failed to Initialize");
e.printStackTrace();
System.exit(1);
}
}
void openLastJob()
{
if (m_lastJobs == null || m_lastJobs.length == 0)
{
error("There is no last job to open.");
return;
}
try
{
readJob( new File(m_lastJobs[0]) );
}
catch (Throwable e)
{
// readJob should take care of details; we just have to notify user
error("Could not open last job", e);
}
}
// This is only public for jas.bean.plot
public static JavaAnalysisStudio getApp()
{
return theApp;
}
// This is only public for jas.bean.plot
public TreeModel getTreeModel()
{
return m_tree.getModel();
}
void setCurrentSelection(CommandProcessor o)
{
if (m_currentSelection != null) getCommandManager().remove(m_currentSelection);
m_currentSelection = o;
if (m_currentSelection != null) getCommandManager().add(m_currentSelection);
}
public void setMessage(String message)
{
m_status.setMessage(message);
}
void setRebinModel(BoundedRangeModel xModel, BoundedRangeModel yModel)
{
m_toolbarHolder.setRebinModel(xModel,yModel);
}
OutputStream getOutputStream(String name)
{
return m_JASConsoleTabbedPane.getOutputStream(name);
}
void setModel(BoundedRangeModel model)
{
m_status.setModel(model);
}
WindowManager getWindowManager()
{
return m_windowManager;
}
public JASPage createNewPage()
{
return newPage(1, 1);
}
/**
* Note: This routine may popup a dialog asking the user which page to use as the
* current plot. It only returns null if the user cancels the dialog.
*/
public JASPage createCurrentPage()
{
// find current plot
final int i = m_windowManager.getSelectedWindow();
final Component c = i < 0 ? null : m_windowManager.getWindow(i);
if (i >= 0 && c instanceof JASPage) return ((JASPage) c);
else
{
final Vector pages = m_windowManager.openPages(JASPage.class);
final int nPages = pages.size();
if (nPages == 0)
{
return newPage(1, 1);
}
else if (nPages == 1)
{
final JASPage page = (JASPage) pages.elementAt(0);
selectPage(page);
return page;
}
else // There are multiple pages to choose from
{
final int[] indexes = new int[nPages + 1]; // the indexes of the JASPage windows
int k = 1;
indexes[0] = -1;
final int n = m_windowManager.getWindowCount();
final JComboBox choices = new JComboBox();
choices.addItem("Create a new window");
for (int j = 0; j < n; j++)
if (m_windowManager.getWindow(j) instanceof JASPage)
{
indexes[k++] = j;
choices.addItem(m_windowManager.getWindowName(j));
}
final JPanel p = new JPanel(new BorderLayout());
p.add(BorderLayout.NORTH, new JLabel("Select the page to show the data on, "+
"or click on \"Cancel\"."));
p.add(BorderLayout.SOUTH, choices);
if (JOptionPane.showConfirmDialog(this, p, "Select a page", JOptionPane.OK_CANCEL_OPTION) ==
JOptionPane.OK_OPTION)
{
final int h = indexes[choices.getSelectedIndex()];
if (h == -1)
{
return newPage(1, 1);
}
else
{
m_windowManager.selectWindow(h);
return getCurrentPage();
}
}
return null;
}
}
}
private void selectPage(JASPage page)
{
final int i = m_windowManager.find(page);
if (i >= 0)
m_windowManager.selectWindow(i);
}
private void exit() throws JASException, IOException
{
if (querySaveJob())
{
if (!m_noTopBottomSplitPane) {
m_topBottomSplitPane.saveState();
}
m_leftRightSplitPane.saveState();
if (m_job != null) m_job.close();
// Save window size and position
if (getFrame().getBounds().x > 0)
userProp.setRectangle("Window",getFrame().getBounds());
/*
* The above if tests whether the frame is open. Often in Windows, users right
* click on the icon when the frame is collapsed to close the application.
* Previously, that caused the application to save its bounds with negative values
* for x and y and upon reopen, the frame would be collapsed. Now, the frame
* bounds are not saved when the frame is collapsed (i.e., when
* getFrame().getBounds().x < 0) and that last saze is used.
*/
userProp.setBoolean("StatusBarVisible",m_statusBarVisible);
userProp.setStringArray("LastJobs", m_lastJobs);
userProp.setStringArray("LastFiles",m_lastFiles);
try
{
userProp.save();
}
catch (FileNotFoundException e)
{
error("Could not save properties", e);
}
// System.exit(0);
close();
}
}
private XMLMenuBuilder xmb;
public XMLMenuBuilder getXMLMenuBuilder() {
return xmb;
}
protected static final class AppCloser extends WindowAdapter
{
AppCloser()
{
}
public void windowClosing(WindowEvent e)
{
JavaAnalysisStudio app = JavaAnalysisStudio.getApp();
try
{
app.exit();
}
catch (IOException x)
{
app.error("Error during window close",x);
}
catch (JASException x)
{
app.error("Error during window close",x);
}
}
}
private void readJob(File file) throws Throwable
// responsible for doing all cleanup if read fails !!
{
closeCurrentJob();
// try
// {
// FileInputStream istream = new FileInputStream(file);
// ObjectInputStream p = new JASInputStream(istream);
// Frame frame = getFrame();
// Cursor oldCursor = frame.getCursor();
// frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
// try
// {
// long readCheck = p.readLong();
// if (readCheck != checkWord) throw new JASException("File does not contain a Java Analysis Studio Job");
// double v = p.readDouble();
// String s = (String) p.readObject();
//
// if (v > getVersionNumber()) throw new JASException("File was written with newer version of Java Analysis Studio - Cannot be read");
// if (v < getVersionNumber()) System.err.println("Reading file written with JAS version: "+v+" "+s);
//
// setJob( (JASJob) p.readObject(), false );
// m_job.setFilePath(file.getAbsolutePath());
// userProp.setString(m_lastJobPath_Key, file.getParent());
// m_windowManager.restoreState(p);
// updateRecentJobs(file.getAbsolutePath());
// }
// catch (ClassNotFoundException x)
// {
// throw new JASException("Corrupt job file: "+file,x);
// }
// finally
// {
// frame.setCursor(oldCursor);
// p.close();
// }
// }
// // if an exception is thrown, pass it along after closing the error-prone new job and
// // setting an "empty job" in its place
// catch (Throwable e)
// {
// closeCurrentJob();
// setToEmptyJob();
// throw e;
// }
}
private void writeJob(String file) throws IOException
{
// Now uses XML to save entire job, not serialization
XMLWriter xml = new XMLWriter(new FileWriter(file));
//p.writeObject(m_job);
m_job.setFilePath(file);
m_windowManager.saveState(xml);
xml.close();
//if (xml.checkError()) throw new IOException("Error while writing XML file");
}
void updateRecentFiles(File newFile)
{
try
{
m_lastFiles = userProp.updateStringArray(m_lastFiles, newFile.getCanonicalPath(), RecentFilesMenu.length_Key);
}
catch (IOException e)
{
m_lastFiles = userProp.updateStringArray(m_lastFiles, newFile.getAbsolutePath(), RecentFilesMenu.length_Key);
}
}
private void updateRecentJobs(String newJob)
{
m_lastJobs = userProp.updateStringArray(m_lastJobs, newJob, RecentJobsMenu.length_Key);
}
String[] getLastJobs()
{
return m_lastJobs;
}
String[] getLastFiles()
{
return m_lastFiles;
}
void openJob(final File file)
// called from RecentJobs menu
{
try
{
if (file != null && querySaveJob())
{
readJob(file);
}
}
catch (Throwable e)
{
// readJob does cleanup, so all we have to do is notify user
error("Cannot read job file", e);
}
}
public void openFile(File f) throws FileError, JASException, MalformedURLException
{
if (f.getName().endsWith(".java")) openJavaFile(f);
else if (f.getName().endsWith(".javahist")) openJavaHistFile(f);
else if (f.getName().endsWith(".plotml")) openPlotMLFile(f);
//else if (f.getName().endsWith(".aidaml")) openAidaMLFile(f);//comment out before checkin
else if (f.getName().endsWith(".html") ||
f.getName().endsWith(".htm") ) showHTMLPage("HTML Page",new URL("file:"+f.getAbsolutePath()),true);
else
{
// Add any extra filters from DIMs which implement LocalDIM2
Enumeration e = JASRegistry.elements();
while (e.hasMoreElements())
{
Object o = e.nextElement();
if (o instanceof LocalDIM2)
{
LocalDIM2 dim = (LocalDIM2) o;
FileFilter ff = dim.getFileFilter();
if (ff.accept(f))
{
openDataSet(f,dim);
return;
}
}
}
int rc = JOptionPane.showConfirmDialog(this,"Unrecognised file type, open in text editor?");
if (rc == JOptionPane.OK_OPTION) openJavaFile(f);
}
}
private void openDataSet(File f, LocalDIM2 dim) throws FileError, JASException
{
try
{
// There are two cases to worry about
// 1. A local job currently open
// 2. A remote job currently open
if (m_job.getJob() instanceof LocalJob)
{
JASLocalJobBuilder ljb = new JASLocalJobBuilder((LocalJob) m_job.getJob());
dim.setLocalJobBuilder(ljb);
ljb.setDIM(dim);
ljb.createJob(f.getCanonicalPath());
}
else if (querySaveJob()) // Remote job
{
JASLocalJobBuilder ljb = getLocalJobBuilder();
ljb.setJobName("Untitled");
dim.setLocalJobBuilder(ljb);
ljb.setDIM(dim);
ljb.createJob(f.getCanonicalPath());
}
}
catch (IOException x) { throw new FileError("Error opening file",x); }
}
private void openJavaHistFile(File f) throws FileError, JASException
{
if (!(m_job.getJob() instanceof LocalJob))
throw new JASException("You can not read a .javahist file into a remote job");
ObjectInputStream in = null;
try
{
in = new ObjectInputStream(new GZIPInputStream(
new BufferedInputStream(new FileInputStream(f))));
// This works somewhat by magic. If the top item in the file is a Histogram
// or HistogramFolder etc, then it will automatically by hooked into the top
// level HistogramFolderSet by the serialization support in AbstractNamedObject.
// If the top level item is a hep.analysis.JobFolder, we need to do some work
// ourselves.
Object o = in.readObject();
//System.out.print("I got an "+o);
//if (o instanceof hep.analysis.NamedObject)
// System.out.print(" and its parent is "+((hep.analysis.NamedObject) o).getFolder());
//System.out.println();
if (o instanceof hepjas.analysis.NamedObject)
{
hepjas.analysis.NamedObject no = (hepjas.analysis.NamedObject) o;
if (no.getFolder() == null) // Must be a hep.analysis.JobFolder
{
// Note: If we supported multiple simultaneous jobs then it would make sense
// to create a new Job here, instead of shoehorning this in here.
LocalJob local = (LocalJob) m_job.getJob();
jas2.job.JobFolder peer = (jas2.job.JobFolder) local.getTreeRoot();
peer.addNotify(no);
}
}
updateRecentFiles(f);
}
catch (Exception x)
{
throw new FileError("Error reading .javahist file",x);
}
finally
{
try
{
if (in != null) in.close();
}
catch (IOException x) {}
}
}
private void openJavaFile(File f) throws FileError
{
final int n = m_windowManager.getWindowCount();
for (int i = 0; i < n; i++)
{
final Component c = m_windowManager.getWindow(i);
if (c instanceof ProgramPage)
{
final String path = ((ProgramPage) c).getCanonicalPath();
try
{
if (path != null && f.getCanonicalPath().equals(path))
{
m_windowManager.selectWindow(i);
updateRecentFiles(f);
return;
}
}
catch (IOException e)
{
throw new FileError("Error opening java file",e);
}
}
}
m_windowManager.newWindow(f.getName(), new ProgramPage(f));
updateRecentFiles(f);
}
private void openPlotMLFile(File f) throws JASException
{
try
{
XMLHistBuilder xhb = new XMLHistBuilder(new BufferedReader(new FileReader(f)),f.getName());
JASPage page = new JASPage(1,1);
xhb.modifyPlot(page.getCurrentPlot());
m_windowManager.newWindow("PlotML",page);
updateRecentFiles(f);
}
catch (Throwable t)
{
error("Error reading PlotML file",t);
}
}
//comment this method out before checkin
/**private void openAidaMLFile(File f) throws JASException
{
try
{
AidaXMLHistBuilder axhb = new AidaXMLHistBuilder(new BufferedReader(new FileReader(f)),f.getName());
JASPage page = new JASPage(1,1);
axhb.modifyPlot(page.getCurrentPlot());
m_windowManager.newWindow("AidaML",page);
}
catch (Throwable t)
{
error("Error reading AidaML file",t);
}
}*/
private void showHTMLPage(String title,URL url,boolean forceNewPage)
{
Vector pages = m_windowManager.openPages(HTMLPage.class);
if (forceNewPage || pages.isEmpty())
{
m_windowManager.newWindow(title,new HTMLPage(url));
}
else
{
HTMLPage page = (HTMLPage) pages.elementAt(0);
page.showURL(url);
m_windowManager.selectWindow(m_windowManager.find(page));
}
}
JASLocalJobBuilder getLocalJobBuilder()
{
return new JASLocalJobBuilder();
}
/*
* returns false to indicate that the operation calling querySaveJob should
* be aborted
*/
private boolean querySaveJob() throws IOException, JASException
{
boolean windowHasChanged = windowHasChanged();
boolean jobHasChanged = m_job.isChanged();
// Currently we dont test for windowListChanged because the initial HTML page
// counts as a change, but should not.
if (jobHasChanged || windowHasChanged) // || m_windowManager.windowListChanged())
{
int rc = JOptionPane.showConfirmDialog
(this,"Save changes to job "+m_job.getName()+"?",
"Save Changes?",JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
if (rc == JOptionPane.CANCEL_OPTION) return false;
if (rc == JOptionPane.CLOSED_OPTION) return false;
if (rc == JOptionPane.YES_OPTION)
{
if (jobSavingDisabled) throw new NotImplemented("Job Saving and Restoring");
return saveJob();
}
}
return true;
}
private boolean windowHasChanged()
{
final int n = m_windowManager.getWindowCount();
for (int i = 0; i < n; i++)
{
Component c = m_windowManager.getWindow(i);
if (c instanceof ChangableContainer && ((ChangableContainer) c).hasChanged())
return true;
}
return false;
}
boolean saveJob() throws IOException
{
String file = m_job.getFilePath();
if (file == null) return saveJobAs();
writeJob(file);
updateRecentJobs(file);
return true;
}
boolean saveJobAs() throws IOException
{
JFileChooser dlg = new JFileChooser(userProp.getString(m_lastJobPath_Key, System.getProperty("user.home")));
dlg.setDialogTitle("Save Job As...");
dlg.setFileFilter(new JASFileFilter());
dlg.setSelectedFile(new File(m_job.getName().concat(".jas")));
if (dlg.showSaveDialog(getFrame()) != JFileChooser.APPROVE_OPTION) return false;
File file = dlg.getSelectedFile();
if (! file.getName().endsWith(".jas")) file = new File(file.getAbsolutePath().concat(".jas"));
writeJob(file.getAbsolutePath());
updateRecentJobs(file.getAbsolutePath());
userProp.setString(m_lastJobPath_Key, file.getParent());
return true;
}
void closeCurrentJob()
{
m_job.close();
}
void setToEmptyJob()
{
// Create a local job with no dataset
String jobName = "Default Job";
JASJob m_job = new JASJob(jobName);
LocalJob localJob = new LocalJob(m_job, jobName);
m_job.setJob(localJob);
setJob(m_job, true);
}
public void setJob(JASJob job, boolean newJob)
{
// closeCurrentJob must be called before this method
if (newJob)
{
/*
* If it is a new job then we want to clear out all of the
* old windows and put in the default first page. Otherwise,
* WindowManager.restoreState() will set up the windows when
* the old job is loaded.
*/
m_windowManager.closeAllWindows();
newPage(1, 1);
}
m_job = job;
m_job.setTreeModel(m_tree);
m_job.setEventSourceModel(m_toolbarHolder.getEventSourceComboBox());
}
private class JASCommand extends JASCommandProcessor
{
void forceSetChanged()
{
setChanged();
}
public void onNewJob() throws IOException, JASException
{
if (querySaveJob()) new JASWizard(getFrame(), "New Job Wizard", new NewJobPage());
}
public void onReconnect() throws ConnectFailed, IOException, JASException
{
if (querySaveJob()) new JASWizard(getFrame(), "Connect to Server", new ConnectPage());
}
public void onOpenJob() throws IOException, JASException
{
if (jobSavingDisabled) throw new NotImplemented("Saving and restoring jobs");
JFileChooser dlg = new JFileChooser(userProp.getString(m_lastJobPath_Key, System.getProperty("user.home")));
dlg.setDialogTitle("Open Job...");
dlg.setFileFilter(new JASFileFilter());
if (dlg.showOpenDialog(getFrame()) == JFileChooser.APPROVE_OPTION)
{
final File file = dlg.getSelectedFile();
try
{
readJob(file);
}
catch (Throwable e)
{
// readJob is responsible for cleanup, so we just have to notify users
error("Could not open job", e);
}
finally
{
setChanged();
}
}
}
public void onOpen() throws FileError, JASException, MalformedURLException
{
JFileChooser dlg = new JFileChooser(userProp.getString("LastProgramPath", System.getProperty("user.home")));
dlg.setDialogTitle("Open File...");
AllSupportedFileFilter all = new AllSupportedFileFilter();
// Add any extra filters from DIMs which implement LocalDIM2
Enumeration e = JASRegistry.elements();
while (e.hasMoreElements())
{
Object o = e.nextElement();
if (o instanceof LocalDIM2)
{
FileFilter ff = ((LocalDIM2) o).getFileFilter();
all.add(ff);
dlg.addChoosableFileFilter(ff);
}
}
FileFilter ff = new FileTypeFileFilter("html","HTML File (*.html)");
all.add(ff);
dlg.addChoosableFileFilter(ff);
ff = new FileTypeFileFilter("javahist","Java Histogram File (*.javahist)");
all.add(ff);
dlg.addChoosableFileFilter(ff);
ff = new FileTypeFileFilter("plotml","XML Plot File (*.plotml)");
all.add(ff);
dlg.addChoosableFileFilter(ff);
ff = new FileTypeFileFilter("java","Java File (*.java)");
all.add(ff);
dlg.addChoosableFileFilter(ff);
//comment out next 3 lines before check in
//ff = new FileTypeFileFilter("aidaml","Aida XML Plot File (*.aidaml)");
//all.add(ff);
//dlg.addChoosableFileFilter(ff);
dlg.setFileFilter(all);
if (dlg.showOpenDialog(getFrame()) == JFileChooser.APPROVE_OPTION)
{
final File f = dlg.getSelectedFile();
userProp.setString("LastProgramPath", f.getParent());
openFile(f);
}
}
public void onNewProgramWizard()
{
onProgramUsingWizard();
}
public void onProgramUsingWizard()
{
new JASWizard(getFrame(), "New Program Page Wizard", new NewProgramPage());
}
public void onBlankProgramPage()
{
final ProgramPage p = new ProgramPage();
p.setClassName("Untitled");
m_windowManager.newWindow("Untitled ", p); // extra space for file extension
}
public void onExit() throws JASException, IOException
{
exit();
}
public void onHome() throws IOException
{
showHTMLPage("Welcome",m_homePage,false);
}
public void onWebPage() throws IOException
{
Vector pages = m_windowManager.openPages(HTMLPage.class);
WebPageDialog dlg = new WebPageDialog(getFrame(),!pages.isEmpty());
if (dlg.doModal()) showHTMLPage("Web Page",dlg.getURL(),dlg.getNewPage());
}
public void onStatusBar(boolean b)
{
setStatusBarVisible(b);
}
public void onOptions()
{
new JASOptionsDialog(getFrame());
}
public void onRegistries()
{
new JASRegistryDialog(getFrame());
}
public void enableStatusBar(JASCheckboxState state)
{
state.setCheckbox(m_statusBarVisible);
state.setEnabled(true);
}
public void onAbout()
{
Dialog dlg = new AboutBox(JavaAnalysisStudio.this.getFrame());
dlg.show();
}
public void onSubmitBugReport() throws MalformedURLException, IOException
{
URL bugURL = new URL("http://www-sldnt.slac.stanford.edu/jas/bugs/bugreport_form.asp");
showHTMLPage("Bug Report",bugURL,true);
}
public void onReleaseNotes() throws MalformedURLException, IOException
{
showHelpTopic("relnotes");
}
public void onCheckVersion(){
JASVersion checkversion = new JASVersion(getFrame(),"JAS",versionURL,getVersionNumber(),userProp);
checkversion.showOptionsDialog();
}
public void onPluginManager(){
if(pluginmanager.getReadPluginXMLOK())pluginmanager.showPluginManager(getFrame());
else{
pluginmanager.initializePluginList();
if(pluginmanager.getReadPluginXMLOK())pluginmanager.showPluginManager(getFrame());
}
}
public void onTutorial() throws MalformedURLException, IOException
{
showHelpTopic("tutorial.part1");
}
public void onWelcome() throws MalformedURLException, IOException
{
showHelpTopic("tutorial.jasintro");
}
public void onHelpContents() throws MalformedURLException, IOException
{
showHelpContents();
}
public void onSearch() throws MalformedURLException, IOException
{
showHelpSearch();
}
public void onHelpIndex() throws MalformedURLException, IOException
{
showHelpIndex();
}
public void onheppackages() throws MalformedURLException, IOException
{
showHelpTopic("API.hepPackages.packageList");
}
public void onjaspackages() throws MalformedURLException, IOException
{
showHelpTopic("API.jasPackages.packageList");
}
public void enableTabbedPanels(JASCheckboxState state)
{
enableWM(state, m_TabbedWM);
}
public void onTabbedPanels()
{
setWM(m_TabbedWM);
}
public void enableInternalFrames(JASCheckboxState state)
{
enableWM(state, m_InternalWM);
}
public void onInternalFrames()
{
setWM(m_InternalWM);
}
private void enableWM(JASCheckboxState state, String name)
{
state.setCheckbox(m_windowManager.getClass().getName().equals(name));
try
{
state.setEnabled(Class.forName(name) != null);
}
catch (Exception e)
{
state.setEnabled(false);
}
}
private void setWM(final String name)
{
if (m_windowManager.getClass().getName().equals(name)) return;
// no point in doing anything if this one is already selected
WindowManager oldManager = m_windowManager;
WindowItem[] wa = oldManager.getItems();
Vector l = oldManager.getPageListeners();
try
{
//m_topBottomSplitPane.saveState();
//m_leftRightSplitPane.saveState();
m_windowManager = (WindowManager) Class.forName(name).newInstance();
JComponent c = (JComponent) m_windowManager;
c.setMinimumSize(new Dimension(40, 40));
m_leftRightSplitPane.setRightComponent(c);
m_leftRightSplitPane.validate(); // I don't think revalidate() is needed here.
//m_topBottomSplitPane.restoreState();
c.repaint();
userProp.setString("WindowManager", name);
m_windowManager.initialize(wa, l);
}
catch (Exception e)
{
error("Could not open window manager "+ name, e);
m_windowManager = oldManager;
}
setChanged();
}
public void enableWindows(JASCheckboxState state)
{
enableLAF(state, m_WindowsLAF);
}
public void onWindows() throws Exception
{
onLAF(m_WindowsLAF);
}
public void enableMotif(JASCheckboxState state)
{
enableLAF(state, m_MotifLAF);
}
public void onMotif() throws Exception
{
onLAF(m_MotifLAF);
}
public void enableJava(JASCheckboxState state)
{
enableLAF(state, m_JavaLAF);
}
public void onJava() throws Exception
{
onLAF(m_JavaLAF);
}
private void enableLAF(JASCheckboxState state, String lafName)
{
try
{
Class c = Class.forName(lafName);
LookAndFeel laf = (LookAndFeel) c.newInstance();
state.setCheckbox(UIManager.getLookAndFeel().getName().equals(laf.getName()));
state.setEnabled(laf.isSupportedLookAndFeel());
}
catch (Exception e)
{
state.setEnabled(false);
}
}
private void onLAF(String lafName) throws Exception
{
//m_topBottomSplitPane.saveState();
//m_leftRightSplitPane.saveState();
UIManager.setLookAndFeel(lafName);
SwingUtilities.updateComponentTreeUI(JavaAnalysisStudio.this.getFrame());
//m_topBottomSplitPane.restoreState();
userProp.put("LookAndFeel", lafName);
setChanged();
}
public void onEnableToolTips(boolean value)
{
ToolTipManager.sharedInstance().setEnabled(value);
userProp.setBoolean("EnableToolTips",value);
}
public void enableEnableToolTips(JASCheckboxState state)
{
state.setCheckbox(ToolTipManager.sharedInstance().isEnabled());
state.setEnabled(true);
}
public void enableFullScreen(JASState state)
{
state.setEnabled(getWindowManager().getSelectedWindow() >= 0);
}
public void onFullScreen()
{
getWindowManager().doFullScreen();
}
public void on1x1()
{
newPage(1,1);
}
public void on1x2()
{
newPage(1,2);
}
public void on2x1()
{
newPage(2,1);
}
public void on2x2()
{
newPage(2,2);
}
public void on3x3()
{
newPage(3,3);
}
public void on4x4()
{
newPage(4,4);
}
public void onStop()
{
m_stopMan.stop();
}
public void enableStop(JASState state)
{
state.setEnabled(m_stopMan.getStopEnabled());
}
}
StoppableExecutionMonitor registerStoppable(StoppableExecution stoppable)
{
return m_stopMan.registerStoppable(stoppable);
}
private class JASStoppableManager
{
StoppableExecutionMonitor registerStoppable(StoppableExecution stoppable)
{
JASStoppableExecutionMonitor monitor =
new JASStoppableExecutionMonitor(stoppable);
m_stoppables.addElement(monitor);
return monitor;
}
void removeStoppable(StoppableExecutionMonitor monitor)
{
m_stoppables.removeElement(monitor);
}
void stop()
{
Enumeration e = m_stoppables.elements();
JASStoppableExecutionMonitor monitor;
while (e.hasMoreElements())
{
monitor = (JASStoppableExecutionMonitor) e.nextElement();
if (monitor.isRunning())
monitor.stop();
}
m_jasCommand.forceSetChanged();
}
boolean getStopEnabled()
{
Enumeration e = m_stoppables.elements();
while (e.hasMoreElements())
{
if (((JASStoppableExecutionMonitor) e.nextElement()).isRunning())
return true;
}
return false;
}
private Vector m_stoppables = new Vector();
}
private class JASStoppableExecutionMonitor implements StoppableExecutionMonitor
{
JASStoppableExecutionMonitor(StoppableExecution stoppable)
{
m_stoppable = stoppable;
doStopEnabling();
}
boolean isRunning()
{
return m_stoppable.isRunning();
}
public void setProgressModel(BoundedRangeModel model) // optional (overrides previous progress model)
{
m_status.setModel(model);
}
public void doStopEnabling()
{
m_jasCommand.forceSetChanged();
}
public void end() // done for good
{
m_stopMan.removeStoppable(this);
}
void stop()
{
m_stoppable.stop();
}
private StoppableExecution m_stoppable;
}
final private class JASFitListener implements FitListener
{
public void fitStarted(final Fitter fitter)
{
new FitWatcher(fitter);
}
}
private class FitWatcher implements Observer, StoppableExecution
{
private StoppableExecutionMonitor m_stopMonitor;
private BoundedRangeModel model;
private Fitter m_fitter;
private final java.text.NumberFormat format =
java.text.NumberFormat.getInstance();
private String m_funcTitle;
FitWatcher(final Fitter fit)
{
format.setMaximumFractionDigits(6);
model = m_status.getModel();
model.setMinimum(0);
model.setMaximum(100);
m_fitter = fit;
m_fitter.addObserver(this);
m_stopMonitor = registerStoppable(this);
m_funcTitle = m_fitter.getFunction().getTitle();
}
Fitter clearFit()
{
Fitter fit = m_fitter;
if (fit != null)
{
fit.deleteObserver(this);
fit.getFunction().clearFit();
m_fitter = null;
m_stopMonitor.end();
}
return fit;
}
public void update(Observable obs, Object arg)
{
if (arg instanceof FitUpdate)
{
FitUpdate fu = (FitUpdate) arg;
int state = fu.getState();
if (state == Fitter.OUTAHERE)
{
clearFit();
}
else
{
model.setValue( fu.getPercent() );
if (state == Fitter.FAILED)
{
setMessage("Fit failed. Exception was: "+ fu.getReason());
clearFit();
}
else if (state == Fitter.FIT)
setMessage(m_funcTitle +" fit complete. \u03c7\u00b2 = "+
format.format( m_fitter.getChiSquared() ));
else if (state == Fitter.FITTING)
setMessage("Now fitting function "+ m_funcTitle);
m_stopMonitor.doStopEnabling();
}
if (m_fitter != null)
m_fitter.getFunction().setChanged();
}
}
public boolean isRunning()
{
return m_fitter != null && m_fitter.getState() == Fitter.FITTING;
}
public void stop()
{
if (m_fitter != null)
{
m_fitter.stop();
m_fitter.deleteObserver(this);
m_fitter.getFunction().clearFit();
m_fitter = null;
m_status.setMessage("Fitter stopped before completion");
m_status.getModel().setValue(0);
}
}
}
private class DoubleClickAdaptor implements MouseListener, CommandSource
{
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2)
{
if (m_target != null) m_target.invoke();
}
}
public void mousePressed(MouseEvent e){};
public void mouseReleased(MouseEvent e){};
public void mouseEntered(MouseEvent e){};
public void mouseExited(MouseEvent e){};
public String getCommand()
{
return "DoubleClick";
}
public CommandTarget getTarget()
{
return m_target;
}
public boolean setTarget(CommandTarget target)
{
if (target instanceof SimpleCommandTarget)
{
m_target = (SimpleCommandTarget) target;
return true;
}
return false;
}
public void clearTarget()
{
m_target = null;
}
private SimpleCommandTarget m_target;
}
private class SelectAdaptor implements TreeSelectionListener , CommandSource
{
public void valueChanged(TreeSelectionEvent e)
{
if (m_target != null && e.isAddedPath()) m_target.invoke();
}
public String getCommand()
{
return "Select";
}
public CommandTarget getTarget()
{
return m_target;
}
public boolean setTarget(CommandTarget target)
{
if (target instanceof SimpleCommandTarget)
{
m_target = (SimpleCommandTarget) target;
return true;
}
return false;
}
public void clearTarget()
{
m_target = null;
}
private SimpleCommandTarget m_target;
}
public MLPArrowFactory getTheArrowFactory() {
// TODO Auto-generated method stub
return null;
}
public MLPLabelFactory getTheLabelFactory() {
// TODO Auto-generated method stub
return null;
}
public MoverLayeredPane getMLP() {
// TODO Auto-generated method stub
return null;
}
public MultiFunctionPanel getMFP() {
// TODO Auto-generated method stub
return null;
}
}//JavaAnalysisStudio
Ads help maintain this website.