import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
+import jalview.api.StructureSelectionManagerProvider;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.gui.ImageExporter.ImageWriterI;
import jalview.io.IdentifyFile;
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
+import jalview.jbgui.GDesktop;
import jalview.jbgui.GSplitFrame;
import jalview.jbgui.GStructureViewer;
import jalview.project.Jalview2XML;
import jalview.util.Platform;
import jalview.util.UrlConstants;
import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.jws1.Discoverer;
import jalview.ws.params.ParamManager;
import jalview.ws.utils.UrlDownloadClient;
* @version $Revision: 1.155 $
*/
@SuppressWarnings("serial")
-public class Desktop extends jalview.jbgui.GDesktop
+public class Desktop extends GDesktop
implements DropTargetListener, ClipboardOwner, IProgressIndicator,
- jalview.api.StructureSelectionManagerProvider
+ StructureSelectionManagerProvider, ApplicationSingletonI
{
+
private final static int DEFAULT_MIN_WIDTH = 300;
private final static int DEFAULT_MIN_HEIGHT = 250;
listener);
}
- /**
- * Singleton Desktop instance only in Java;
- */
- private static Desktop instance;
-
- public static Desktop getInstance()
- {
- if (instance == null)
- {
- new Desktop(true);
- }
- Desktop d;
- @SuppressWarnings("unused")
- ThreadGroup g = Thread.currentThread().getThreadGroup();
- /**
- * @j2sNative d = g._jalviewDesktopInstance;
- */
- {
- d = instance;
- }
- return d;
- }
-
- private static void setInstance(Desktop d)
- {
- @SuppressWarnings("unused")
- ThreadGroup g = Thread.currentThread().getThreadGroup();
- /**
- * @j2sNative g._jalviewDesktopInstance = d;
- */
- {
- instance = d;
- }
- }
-
- private MyDesktopPane desktopPane;
-
public static MyDesktopPane getDesktopPane()
{
- return getInstance().desktopPane;
+ Desktop desktop = Desktop.getInstance();
+ return desktop == null ? null : desktop.desktopPane;
}
- private void setDesktopPane(MyDesktopPane pane)
+ public static StructureSelectionManager getStructureSelectionManager()
{
- getInstance().desktopPane = pane;
+ return StructureSelectionManager
+ .getStructureSelectionManager(getInstance());
}
static int openFrameCount = 0;
static final int yOffset = 30;
- public jalview.ws.jws1.Discoverer discoverer;
+ public Discoverer discoverer;
public Object[] jalviewClipboard;
private static int fileLoadingCount = 0;
- public JInternalFrame conservationSlider, PIDSlider;
+ public JInternalFrame conservationSlider;
- private boolean instanceOnly;
+ public JInternalFrame PIDSlider;
+
+ /**
+ * just an instance (for testng, probably); no actual frames
+ *
+ * This flag, when set true, allows a headless-like operation, with a Desktop
+ * object but no actual frames. Though not headless, this option disallows
+ * dialogs to run in test environments.
+ *
+ * It is set by invoking the Desktop(true) constructor.
+ *
+ */
+ boolean instanceOnly;
class MyDesktopManager implements DesktopManager
{
} catch (NullPointerException npe)
{
Point p = getMousePosition();
- getInstance().showPasteMenu(p.x, p.y);
+ showPasteMenu(p.x, p.y);
}
}
public void endDraggingFrame(JComponent f)
{
delegate.endDraggingFrame(f);
- getDesktopPane().repaint();
+ desktopPane.repaint();
}
@Override
public void endResizingFrame(JComponent f)
{
delegate.endResizingFrame(f);
- getDesktopPane().repaint();
+ desktopPane.repaint();
}
@Override
}
+ public MyDesktopPane desktopPane;
+
+ /**
+ * Answers an 'application scope' singleton instance of this class. Separate
+ * SwingJS 'applets' running in the same browser page will each have a
+ * distinct instance of Desktop.
+ *
+ * @return
+ */
+ public static Desktop getInstance()
+ {
+ return Jalview.isHeadlessMode() ? null
+ : (Desktop) ApplicationSingletonProvider
+ .getInstance(Desktop.class);
+ }
+
+ /**
+ * For TestNG, this constructor can be utilized to allow the creation of a
+ * singleton Desktop instance without the formation of frames and, especially,
+ * not involving dialogs. Cache.log is also initialized for some tests that
+ * require it despite there being no Desktop.
+ *
+ * @param forInstance
+ */
public Desktop(boolean forInstance)
{
+ ApplicationSingletonProvider.setInstance(Desktop.class, this);
+ Cache.initLogger();
instanceOnly = true;
- setInstance(this);
}
+
/**
- * Creates a new Desktop object.
+ * Private constructor enforces singleton pattern. It is called by reflection
+ * from ApplicationSingletonProvider.getInstance().
*/
- public Desktop()
+ @SuppressWarnings("unused")
+ private Desktop()
{
- /**
- * A note to implementors. It is ESSENTIAL that any activities that might
- * block are spawned off as threads rather than waited for during this
- * constructor.
- */
- setInstance(this);
- if (!Platform.isJS())
- {
- doVamsasClientCheck();
- }
-
- doConfigureStructurePrefs();
- setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
- false);
- boolean showjconsole = jalview.bin.Cache.getDefault("SHOW_JAVA_CONSOLE",
- false);
- setDesktopPane(new MyDesktopPane(selmemusage));
-
- showMemusage.setSelected(selmemusage);
- getDesktopPane().setBackground(Color.white);
- getContentPane().setLayout(new BorderLayout());
- // alternate config - have scrollbars - see notes in JAL-153
- // JScrollPane sp = new JScrollPane();
- // sp.getViewport().setView(desktop);
- // getContentPane().add(sp, BorderLayout.CENTER);
-
- // BH 2018 - just an experiment to try unclipped JInternalFrames.
- if (Platform.isJS())
+ Cache.initLogger();
+ try
{
- getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
- }
+ /**
+ * A note to implementors. It is ESSENTIAL that any activities that might
+ * block are spawned off as threads rather than waited for during this
+ * constructor.
+ */
+ if (!Platform.isJS())
+ {
+ doVamsasClientCheck();
+ }
- getContentPane().add(getDesktopPane(), BorderLayout.CENTER);
- getDesktopPane().setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
+ doConfigureStructurePrefs();
+ setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
+ false);
+ boolean showjconsole = jalview.bin.Cache
+ .getDefault("SHOW_JAVA_CONSOLE", false);
+ desktopPane = new MyDesktopPane(selmemusage);
- // This line prevents Windows Look&Feel resizing all new windows to maximum
- // if previous window was maximised
- getDesktopPane().setDesktopManager(new MyDesktopManager(
- (Platform.isWindowsAndNotJS() ? new DefaultDesktopManager()
- : Platform.isAMacAndNotJS()
- ? new AquaInternalFrameManager(
- getDesktopPane().getDesktopManager())
- : getDesktopPane().getDesktopManager())));
+ showMemusage.setSelected(selmemusage);
+ desktopPane.setBackground(Color.white);
+ getContentPane().setLayout(new BorderLayout());
+ // alternate config - have scrollbars - see notes in JAL-153
+ // JScrollPane sp = new JScrollPane();
+ // sp.getViewport().setView(desktop);
+ // getContentPane().add(sp, BorderLayout.CENTER);
- Rectangle dims = getLastKnownDimensions("");
- if (dims != null)
- {
- setBounds(dims);
- }
- else
- {
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- int xPos = Math.max(5, (screenSize.width - 900) / 2);
- int yPos = Math.max(5, (screenSize.height - 650) / 2);
- setBounds(xPos, yPos, 900, 650);
- }
+ // BH 2018 - just an experiment to try unclipped JInternalFrames.
+ if (Platform.isJS())
+ {
+ getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
+ }
- if (!Platform.isJS())
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
+ getContentPane().add(desktopPane, BorderLayout.CENTER);
+ desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
- jconsole = new Console(this, showjconsole);
- // add essential build information
- jconsole.setHeader("Jalview Version: "
- + jalview.bin.Cache.getProperty("VERSION") + "\n"
- + "Jalview Installation: "
- + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
- + "\n" + "Build Date: "
- + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
- + "Java version: " + System.getProperty("java.version") + "\n"
- + System.getProperty("os.arch") + " "
- + System.getProperty("os.name") + " "
- + System.getProperty("os.version"));
+ // This line prevents Windows Look&Feel resizing all new windows to
+ // maximum
+ // if previous window was maximised
+ desktopPane.setDesktopManager(new MyDesktopManager(
+ (Platform.isWindowsAndNotJS() ? new DefaultDesktopManager()
+ : Platform.isAMacAndNotJS()
+ ? new AquaInternalFrameManager(
+ desktopPane.getDesktopManager())
+ : desktopPane.getDesktopManager())));
- showConsole(showjconsole);
+ Rectangle dims = getLastKnownDimensions("");
+ if (dims != null)
+ {
+ setBounds(dims);
+ }
+ else
+ {
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ int xPos = Math.max(5, (screenSize.width - 900) / 2);
+ int yPos = Math.max(5, (screenSize.height - 650) / 2);
+ setBounds(xPos, yPos, 900, 650);
+ }
- showNews.setVisible(false);
+ // Note that this next syntax, checking for Platform.isJS and also
+ // escaping the code using @j2sIgnore, serves two purposes. It gives
+ // us an easily findable tag, Platform.isJS(), to places in the code where
+ // there is something different about the SwingJS implementation. Second,
+ // it deletes the unneeded Java-only code form the JavaScript version
+ // completely (@j2sIgnore), since it will never be used there.
- experimentalFeatures.setSelected(showExperimental());
+ if (!Platform.isJS())
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
- getIdentifiersOrgData();
+ jconsole = new Console(this, showjconsole);
+ // add essential build information
+ jconsole.setHeader("Jalview Version: "
+ + jalview.bin.Cache.getProperty("VERSION") + "\n"
+ + "Jalview Installation: "
+ + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
+ + "\n" + "Build Date: "
+ + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
+ + "\n" + "Java version: "
+ + System.getProperty("java.version") + "\n"
+ + System.getProperty("os.arch") + " "
+ + System.getProperty("os.name") + " "
+ + System.getProperty("os.version"));
- checkURLLinks();
+ showConsole(showjconsole);
- // Spawn a thread that shows the splashscreen
+ showNews.setVisible(false);
- SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- new SplashScreen();
- }
- });
+ experimentalFeatures.setSelected(showExperimental());
- // Thread off a new instance of the file chooser - this reduces the time
- // it
- // takes to open it later on.
- new Thread(new Runnable()
- {
- @Override
- public void run()
+ getIdentifiersOrgData();
+
+ checkURLLinks();
+
+ // Spawn a thread that shows the splashscreen
+
+ SwingUtilities.invokeLater(new Runnable()
{
- Cache.log.debug("Filechooser init thread started.");
- String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
- JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
- fileFormat);
- Cache.log.debug("Filechooser init thread finished.");
- }
- }).start();
- // Add the service change listener
- changeSupport.addJalviewPropertyChangeListener("services",
- new PropertyChangeListener()
- {
+ @Override
+ public void run()
+ {
+ new SplashScreen();
+ }
+ });
- @Override
- public void propertyChange(PropertyChangeEvent evt)
+ // Thread off a new instance of the file chooser - this reduces the time
+ // it
+ // takes to open it later on.
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Cache.log.debug("Filechooser init thread started.");
+ String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+ JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
+ fileFormat);
+ Cache.log.debug("Filechooser init thread finished.");
+ }
+ }).start();
+ // Add the service change listener
+ changeSupport.addJalviewPropertyChangeListener("services",
+ new PropertyChangeListener()
{
- Cache.log.debug("Firing service changed event for "
- + evt.getNewValue());
- JalviewServicesChanged(evt);
- }
-
- });
- }
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ Cache.log.debug("Firing service changed event for "
+ + evt.getNewValue());
+ JalviewServicesChanged(evt);
+ }
- this.setDropTarget(new java.awt.dnd.DropTarget(getDesktopPane(), this));
+ });
- this.addWindowListener(new WindowAdapter()
- {
- @Override
- public void windowClosing(WindowEvent evt)
- {
- quit();
}
- });
- MouseAdapter ma;
- this.addMouseListener(ma = new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent evt)
+ this.setDropTarget(new java.awt.dnd.DropTarget(desktopPane, this));
+
+ this.addWindowListener(new WindowAdapter()
{
- if (evt.isPopupTrigger()) // Mac
+ @Override
+ public void windowClosing(WindowEvent evt)
{
- showPasteMenu(evt.getX(), evt.getY());
+ quit();
}
- }
+ });
- @Override
- public void mouseReleased(MouseEvent evt)
+ MouseAdapter ma;
+ this.addMouseListener(ma = new MouseAdapter()
{
- if (evt.isPopupTrigger()) // Windows
+ @Override
+ public void mousePressed(MouseEvent evt)
{
- showPasteMenu(evt.getX(), evt.getY());
+ if (evt.isPopupTrigger()) // Mac
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
}
- }
- });
- getDesktopPane().addMouseListener(ma);
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
+ }
+ });
+ desktopPane.addMouseListener(ma);
+ } catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
}
/**
}
}
}).start();
- ;
+
}
@Override
public void run()
{
long now = System.currentTimeMillis();
- Desktop.getInstance().setProgressBar(
+ setProgressBar(
MessageManager.getString("status.refreshing_news"), now);
jvnews.refreshNews();
- Desktop.getInstance().setProgressBar(null, now);
+ setProgressBar(null, now);
jvnews.showNews();
}
}).start();
FileFormatI format = new IdentifyFile().identify(file,
DataSourceType.PASTE);
- new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
+ new FileLoader().loadFile(file, DataSourceType.PASTE, format);
}
} catch (Exception ex)
int w, int h, boolean resizable, boolean ignoreMinSize)
{
+
// TODO: allow callers to determine X and Y position of frame (eg. via
// bounds object).
// TODO: consider fixing method to update entries in the window submenu with
// the current window title
frame.setTitle(title);
- if (frame.getWidth() < 1 || frame.getHeight() < 1)
+ if (w > 0 && (frame.getWidth() < 1 || frame.getHeight() < 1))
{
frame.setSize(w, h);
}
// A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
// IF JALVIEW IS RUNNING HEADLESS
// ///////////////////////////////////////////////
- if (getInstance().instanceOnly || Jalview.isHeadlessMode())
+ if (Jalview.isHeadlessMode() || Desktop.getInstance().instanceOnly)
{
return;
}
frame.setIconifiable(resizable);
frame.setOpaque(Platform.isJS());
- if (frame.getX() < 1 && frame.getY() < 1)
+ boolean isEmbedded = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
+ if (!isEmbedded && frame.getX() < 1 && frame.getY() < 1)
{
frame.setLocation(xOffset * openFrameCount,
yOffset * ((openFrameCount - 1) % 10) + yOffset);
{
menuItem.removeActionListener(menuItem.getActionListeners()[0]);
}
- getInstance().windowMenu.remove(menuItem);
- };
+ Desktop.getInstance().windowMenu.remove(menuItem);
+ }
});
menuItem.addActionListener(new ActionListener()
getDesktopPane().add(frame);
- getInstance().windowMenu.add(menuItem);
+ Desktop.getInstance().windowMenu.add(menuItem);
frame.toFront();
try
{
Platform.cacheFileData((File) file);
}
- new FileLoader().LoadFile(null, file, protocol, format);
+ new FileLoader().loadFile(null, file, protocol, format);
}
} catch (Exception ex)
}
}
- new FileLoader().LoadFile(viewport, selectedFile,
+ new FileLoader().loadFile(viewport, selectedFile,
DataSourceType.FILE, format);
}
});
{
if (viewport != null)
{
- new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
+ new FileLoader().loadFile(viewport, url, DataSourceType.URL,
FileFormat.Jalview);
}
else
{
- new FileLoader().LoadFile(url, DataSourceType.URL,
+ new FileLoader().loadFile(url, DataSourceType.URL,
FileFormat.Jalview);
}
}
if (viewport != null)
{
- new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
+ new FileLoader().loadFile(viewport, url, DataSourceType.URL,
format);
}
else
{
- new FileLoader().LoadFile(url, DataSourceType.URL, format);
+ new FileLoader().loadFile(url, DataSourceType.URL, format);
}
}
}
@Override
public void closeAll_actionPerformed(ActionEvent e)
{
+ if (desktopPane == null)
+ {
+ return;
+ }
// TODO show a progress bar while closing?
- JInternalFrame[] frames = getDesktopPane().getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
for (int i = 0; i < frames.length; i++)
{
try
* reset state of singleton objects as appropriate (clear down session state
* when all windows are closed)
*/
- StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(this);
- if (ssm != null)
- {
- ssm.resetAll();
- }
+ getStructureSelectionManager().resetAll();
}
@Override
{
progressPanel = new JPanel(new GridLayout(1, 1));
totalProgressCount = 0;
- getInstance().getContentPane().add(progressPanel, BorderLayout.SOUTH);
+ getContentPane().add(progressPanel, BorderLayout.SOUTH);
}
JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
JProgressBar progressBar = new JProgressBar();
((GridLayout) progressPanel.getLayout()).setRows(
((GridLayout) progressPanel.getLayout()).getRows() + 1);
++totalProgressCount;
- getInstance().validate();
+ validate();
return thisprogress;
}
{
source.viewport.setGatherViewsHere(true);
source.viewport.setExplodedGeometry(source.getBounds());
- JInternalFrame[] frames = getDesktopPane().getAllFrames();
+ JInternalFrame[] frames = getAllFrames();
String viewId = source.viewport.getSequenceSetId();
for (int t = 0; t < frames.length; t++)
});
rthr.start();
}
- };
+ }
});
VamsasStMenu.add(sessit);
}
public JInternalFrame[] getAllFrames()
{
- return getDesktopPane().getAllFrames();
+ return desktopPane.getAllFrames();
}
/**
});
msgPanel.add(jcb);
- JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), msgPanel,
+ JvOptionPane.showMessageDialog(desktopPane, msgPanel,
MessageManager
.getString("label.SEQUENCE_ID_no_longer_used"),
JvOptionPane.WARNING_MESSAGE);
} catch (Exception ex)
{
jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
- JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
+ JvOptionPane.showInternalMessageDialog(desktopPane,
MessageManager.getString("label.couldnt_create_groovy_shell"),
MessageManager.getString("label.groovy_support_failed"),
// todo: changesupport handlers need to be transferred
if (discoverer == null)
{
- discoverer = new jalview.ws.jws1.Discoverer();
+ discoverer = Discoverer.getInstance();
// register PCS handler for getDesktop().
discoverer.addPropertyChangeListener(changeSupport);
}
if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
- t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
+ t2 = jalview.ws.jws2.Jws2Discoverer.getInstance()
.startDiscoverer(changeSupport);
}
Thread t3 = null;
{
if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
{
- final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
+ final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
.getErrorMessages();
if (ermsg != null)
{
public static ParamManager getUserParameterStore()
{
- Desktop d = getInstance();
+ Desktop d = Desktop.getInstance();
if (d.wsparamManager == null)
{
d.wsparamManager = new WsParamSetManager();
} catch (InterruptedException x)
{
}
- ;
}
- if (instanceOnly)
+ System.out.println("Desktop headless or instanceonly" + instanceOnly
+ + " " + Jalview.isHeadlessMode());
+ if (instanceOnly || Jalview.isHeadlessMode())
{
return;
}
String topViewId = myTopFrame.viewport.getSequenceSetId();
String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
- JInternalFrame[] frames = getDesktopPane().getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
for (JInternalFrame frame : frames)
{
if (frame instanceof SplitFrame && frame != source)
public static groovy.ui.Console getGroovyConsole()
{
- return getInstance().groovyConsole;
+ Desktop desktop = Desktop.getInstance();
+ return desktop == null ? null : desktop.groovyConsole;
}
/**
System.err.println(
"Please ignore plist error - occurs due to problem with java 8 on OSX");
}
- ;
}
} catch (Throwable ex)
{
Class<? extends StructureViewerBase> structureViewerClass)
{
List<StructureViewerBase> result = new ArrayList<>();
- JInternalFrame[] frames = Desktop.getInstance().getAllFrames();
+ JInternalFrame[] frames = getAllFrames();
for (JInternalFrame frame : frames)
{