X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FDesktop.java;h=d2f3841e044404e1a3c664c3b0d6d72ce1849b78;hb=45cdda84387bfd8b7383573f9788dd0dd6e70ecd;hp=c835248bc5cd047a615113394e0cc835f85f2200;hpb=53b2ec17b88081e402f60deab2723750bc4867d1;p=jalview.git diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index c835248..d2f3841 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -22,8 +22,10 @@ package jalview.gui; 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.Instance; import jalview.bin.Jalview; import jalview.gui.ImageExporter.ImageWriterI; import jalview.io.BackupFiles; @@ -37,6 +39,7 @@ import jalview.io.FormatAdapter; 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; @@ -135,10 +138,11 @@ import org.stackoverflowusers.file.WindowsShortcut; * @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; @@ -195,7 +199,14 @@ public class Desktop extends jalview.jbgui.GDesktop public static MyDesktopPane getDesktopPane() { - return Instance.getDesktop().desktopPane; + Desktop desktop = Desktop.getInstance(); + return desktop == null ? null : desktop.desktopPane; + } + + public static StructureSelectionManager getStructureSelectionManager() + { + return StructureSelectionManager + .getStructureSelectionManager(getInstance()); } static int openFrameCount = 0; @@ -212,12 +223,21 @@ public class Desktop extends jalview.jbgui.GDesktop private static int fileLoadingCount = 0; - public JInternalFrame conservationSlider, PIDSlider; + public JInternalFrame conservationSlider; + + 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. + * */ - private boolean instanceOnly; + boolean instanceOnly; class MyDesktopManager implements DesktopManager { @@ -344,182 +364,223 @@ public class Desktop extends jalview.jbgui.GDesktop 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; } + /** - * 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. - */ - Instance.setDesktop(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); - desktopPane = new MyDesktopPane(selmemusage); - - 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); - - // 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(desktopPane, BorderLayout.CENTER); - desktopPane.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 - desktopPane.setDesktopManager(new MyDesktopManager( - (Platform.isWindowsAndNotJS() ? new DefaultDesktopManager() - : Platform.isAMacAndNotJS() - ? new AquaInternalFrameManager( - desktopPane.getDesktopManager()) - : desktopPane.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(desktopPane, 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()); + } } - } - }); - desktopPane.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(); + } } /** @@ -595,7 +656,7 @@ public class Desktop extends jalview.jbgui.GDesktop } } }).start(); - ; + } @Override @@ -757,7 +818,7 @@ public class Desktop extends jalview.jbgui.GDesktop 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) @@ -852,13 +913,14 @@ public class Desktop extends jalview.jbgui.GDesktop 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); } @@ -866,7 +928,7 @@ public class Desktop extends jalview.jbgui.GDesktop // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN // IF JALVIEW IS RUNNING HEADLESS // /////////////////////////////////////////////// - if (Instance.getDesktop().instanceOnly || Jalview.isHeadlessMode()) + if (Jalview.isHeadlessMode() || Desktop.getInstance().instanceOnly) { return; } @@ -896,7 +958,8 @@ public class Desktop extends jalview.jbgui.GDesktop 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); @@ -944,8 +1007,8 @@ public class Desktop extends jalview.jbgui.GDesktop { menuItem.removeActionListener(menuItem.getActionListeners()[0]); } - Instance.getDesktop().windowMenu.remove(menuItem); - }; + Desktop.getInstance().windowMenu.remove(menuItem); + } }); menuItem.addActionListener(new ActionListener() @@ -968,7 +1031,7 @@ public class Desktop extends jalview.jbgui.GDesktop getDesktopPane().add(frame); - Instance.getDesktop().windowMenu.add(menuItem); + Desktop.getInstance().windowMenu.add(menuItem); frame.toFront(); try @@ -1025,7 +1088,7 @@ public class Desktop extends jalview.jbgui.GDesktop { if (!internalCopy) { - Instance.getDesktop().jalviewClipboard = null; + Desktop.getInstance().jalviewClipboard = null; } internalCopy = false; @@ -1104,7 +1167,7 @@ public class Desktop extends jalview.jbgui.GDesktop { Platform.cacheFileData((File) file); } - new FileLoader().LoadFile(null, file, protocol, format); + new FileLoader().loadFile(null, file, protocol, format); } } catch (Exception ex) @@ -1161,7 +1224,7 @@ public class Desktop extends jalview.jbgui.GDesktop } } - new FileLoader().LoadFile(viewport, selectedFile, + new FileLoader().loadFile(viewport, selectedFile, DataSourceType.FILE, format); } }); @@ -1235,12 +1298,12 @@ public class Desktop extends jalview.jbgui.GDesktop { 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); } } @@ -1270,12 +1333,12 @@ public class Desktop extends jalview.jbgui.GDesktop 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); } } } @@ -1504,12 +1567,7 @@ public class Desktop extends jalview.jbgui.GDesktop * 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 @@ -2352,7 +2410,7 @@ public class Desktop extends jalview.jbgui.GDesktop }); rthr.start(); } - }; + } }); VamsasStMenu.add(sessit); } @@ -3013,7 +3071,7 @@ public class Desktop extends jalview.jbgui.GDesktop if (Cache.getDefault("SHOW_JWS2_SERVICES", true)) { - t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer() + t2 = jalview.ws.jws2.Jws2Discoverer.getInstance() .startDiscoverer(changeSupport); } Thread t3 = null; @@ -3046,7 +3104,7 @@ public class Desktop extends jalview.jbgui.GDesktop { 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) { @@ -3122,7 +3180,7 @@ public class Desktop extends jalview.jbgui.GDesktop */ public static void showUrl(final String url) { - showUrl(url, Instance.getDesktop()); + showUrl(url, Desktop.getInstance()); } /** @@ -3171,7 +3229,7 @@ public class Desktop extends jalview.jbgui.GDesktop public static ParamManager getUserParameterStore() { - Desktop d = Instance.getDesktop(); + Desktop d = Desktop.getInstance(); if (d.wsparamManager == null) { d.wsparamManager = new WsParamSetManager(); @@ -3252,9 +3310,10 @@ public class Desktop extends jalview.jbgui.GDesktop } catch (InterruptedException x) { } - ; } - if (instanceOnly) + System.out.println("Desktop headless or instanceonly" + instanceOnly + + " " + Jalview.isHeadlessMode()); + if (instanceOnly || Jalview.isHeadlessMode()) { return; } @@ -3463,7 +3522,8 @@ public class Desktop extends jalview.jbgui.GDesktop public static groovy.ui.Console getGroovyConsole() { - return Instance.getDesktop().groovyConsole; + Desktop desktop = Desktop.getInstance(); + return desktop == null ? null : desktop.groovyConsole; } /** @@ -3541,7 +3601,6 @@ public class Desktop extends jalview.jbgui.GDesktop System.err.println( "Please ignore plist error - occurs due to problem with java 8 on OSX"); } - ; } } catch (Throwable ex) {