X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FDesktop.java;h=16603df6309dbb4d184836d4710afcd47865729e;hb=53fe06e7ae7a8c00ec902413391cea15362bdbf2;hp=82d38e34e41bc8cb100375a411019927f760f69d;hpb=006890b02106eb31841e6e84d75f1027434823e0;p=jalview.git diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 82d38e3..16603df 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -25,6 +25,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Point; import java.awt.Rectangle; @@ -47,17 +48,21 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.awt.geom.AffineTransform; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.lang.reflect.Field; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.ListIterator; +import java.util.Locale; import java.util.Vector; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -114,7 +119,9 @@ import jalview.project.Jalview2XML; import jalview.structure.StructureSelectionManager; import jalview.urls.IdOrgSettings; import jalview.util.BrowserLauncher; +import jalview.util.ChannelProperties; import jalview.util.ImageMaker.TYPE; +import jalview.util.LaunchUtils; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.util.ShortcutKeyMaskExWrapper; @@ -134,12 +141,35 @@ public class Desktop extends jalview.jbgui.GDesktop implements DropTargetListener, ClipboardOwner, IProgressIndicator, jalview.api.StructureSelectionManagerProvider { - private static final String CITATION = "

Development managed by The Barton Group, University of Dundee, Scotland, UK.
" - + "

For help, see the FAQ at www.jalview.org/faq and/or join the jalview-discuss@jalview.org mailing list" - + "

If you use Jalview, please cite:" - + "
Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)" - + "
Jalview Version 2 - a multiple sequence alignment editor and analysis workbench" - + "
Bioinformatics doi: 10.1093/bioinformatics/btp033"; + private static final String CITATION; + static + { + URL bg_logo_url = ChannelProperties.getImageURL( + "bg_logo." + String.valueOf(SplashScreen.logoSize)); + URL uod_logo_url = ChannelProperties.getImageURL( + "uod_banner." + String.valueOf(SplashScreen.logoSize)); + boolean logo = (bg_logo_url != null || uod_logo_url != null); + StringBuilder sb = new StringBuilder(); + sb.append( + "

Jalview is free software released under GPLv3.

Development is managed by The Barton Group, University of Dundee, Scotland, UK."); + if (logo) + { + sb.append("
"); + } + sb.append(bg_logo_url == null ? "" + : "\"Barton"); + sb.append(uod_logo_url == null ? "" + : " \"University"); + sb.append( + "

For help, see www.jalview.org/faq and join discourse.jalview.org"); + sb.append("

If you use Jalview, please cite:" + + "
Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)" + + "
Jalview Version 2 - a multiple sequence alignment editor and analysis workbench" + + "
Bioinformatics doi: 10.1093/bioinformatics/btp033"); + CITATION = sb.toString(); + } private static final String DEFAULT_AUTHORS = "The Jalview Authors (See AUTHORS file for current list)"; @@ -153,12 +183,14 @@ public class Desktop extends jalview.jbgui.GDesktop private static final String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES"; - protected static final String CONFIRM_KEYBOARD_QUIT = "CONFIRM_KEYBOARD_QUIT"; + public static final String CONFIRM_KEYBOARD_QUIT = "CONFIRM_KEYBOARD_QUIT"; - public static HashMap savingFiles = new HashMap<>(); + public static HashMap savingFiles = new HashMap(); private JalviewChangeSupport changeSupport = new JalviewChangeSupport(); + public static boolean nosplash = false; + /** * news reader - null if it was never started. */ @@ -364,27 +396,61 @@ public class Desktop extends jalview.jbgui.GDesktop instance = this; doConfigureStructurePrefs(); - setTitle("Jalview " + Cache.getProperty("VERSION")); - /* - if (!Platform.isAMac()) - { - // this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - } - else - { - this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - } - */ + setTitle(ChannelProperties.getProperty("app_name") + " " + + Cache.getProperty("VERSION")); - try - { - APQHandlers.setAPQHandlers(this); - } catch (Throwable t) + /** + * Set taskbar "grouped windows" name for linux desktops (works in GNOME and + * KDE). This uses sun.awt.X11.XToolkit.awtAppClassName which is not + * officially documented or guaranteed to exist, so we access it via + * reflection. There appear to be unfathomable criteria about what this + * string can contain, and it if doesn't meet those criteria then "java" + * (KDE) or "jalview-bin-Jalview" (GNOME) is used. "Jalview", "Jalview + * Develop" and "Jalview Test" seem okay, but "Jalview non-release" does + * not. The reflection access may generate a warning: WARNING: An illegal + * reflective access operation has occurred WARNING: Illegal reflective + * access by jalview.gui.Desktop () to field + * sun.awt.X11.XToolkit.awtAppClassName which I don't think can be avoided. + */ + if (Platform.isLinux()) { - System.out.println("Error setting APQHandlers: " + t.toString()); - // t.printStackTrace(); + if (LaunchUtils.getJavaVersion() >= 11) + { + jalview.bin.Console.info( + "Linux platform only! You may have the following warning next: \"WARNING: An illegal reflective access operation has occurred\"\nThis is expected and cannot be avoided, sorry about that."); + } + try + { + Toolkit xToolkit = Toolkit.getDefaultToolkit(); + Field[] declaredFields = xToolkit.getClass().getDeclaredFields(); + Field awtAppClassNameField = null; + + if (Arrays.stream(declaredFields) + .anyMatch(f -> f.getName().equals("awtAppClassName"))) + { + awtAppClassNameField = xToolkit.getClass() + .getDeclaredField("awtAppClassName"); + } + + String title = ChannelProperties.getProperty("app_name"); + if (awtAppClassNameField != null) + { + awtAppClassNameField.setAccessible(true); + awtAppClassNameField.set(xToolkit, title); + } + else + { + jalview.bin.Console.debug("XToolkit: awtAppClassName not found"); + } + } catch (Exception e) + { + jalview.bin.Console.debug("Error setting awtAppClassName"); + jalview.bin.Console.trace(Cache.getStackTraceString(e)); + } } + setIconImages(ChannelProperties.getIconList()); + addWindowListener(new WindowAdapter() { @@ -395,11 +461,9 @@ public class Desktop extends jalview.jbgui.GDesktop } }); - boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", - false); + boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", false); - boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE", - false); + boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE", false); desktop = new MyDesktopPane(selmemusage); showMemusage.setSelected(selmemusage); @@ -462,15 +526,17 @@ public class Desktop extends jalview.jbgui.GDesktop checkURLLinks(); // Spawn a thread that shows the splashscreen - - SwingUtilities.invokeLater(new Runnable() + if (!nosplash) { - @Override - public void run() + SwingUtilities.invokeLater(new Runnable() { - new SplashScreen(true); - } - }); + @Override + public void run() + { + new SplashScreen(true); + } + }); + } // Thread off a new instance of the file chooser - this reduces the time // it @@ -480,11 +546,11 @@ public class Desktop extends jalview.jbgui.GDesktop @Override public void run() { - Cache.log.debug("Filechooser init thread started."); + jalview.bin.Console.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."); + jalview.bin.Console.debug("Filechooser init thread finished."); } }).start(); // Add the service change listener @@ -495,8 +561,9 @@ public class Desktop extends jalview.jbgui.GDesktop @Override public void propertyChange(PropertyChangeEvent evt) { - Cache.log.debug("Firing service changed event for " - + evt.getNewValue()); + jalview.bin.Console + .debug("Firing service changed event for " + + evt.getNewValue()); JalviewServicesChanged(evt); } }); @@ -535,7 +602,6 @@ public class Desktop extends jalview.jbgui.GDesktop } }); desktop.addMouseListener(ma); - } /** @@ -558,12 +624,13 @@ public class Desktop extends jalview.jbgui.GDesktop .getStructureSelectionManager(this); if (Cache.getDefault(Preferences.ADD_SS_ANN, true)) { - ssm.setAddTempFacAnnot(Cache - .getDefault(Preferences.ADD_TEMPFACT_ANN, true)); - ssm.setProcessSecondaryStructure(Cache - .getDefault(Preferences.STRUCT_FROM_PDB, true)); + ssm.setAddTempFacAnnot( + Cache.getDefault(Preferences.ADD_TEMPFACT_ANN, true)); + ssm.setProcessSecondaryStructure( + Cache.getDefault(Preferences.STRUCT_FROM_PDB, true)); + // JAL-3915 - RNAView is no longer an option so this has no effect ssm.setSecStructServices( - Cache.getDefault(Preferences.USE_RNAVIEW, true)); + Cache.getDefault(Preferences.USE_RNAVIEW, false)); } else { @@ -582,35 +649,39 @@ public class Desktop extends jalview.jbgui.GDesktop @Override public void run() { - Cache.log.debug("Starting news thread."); + jalview.bin.Console.debug("Starting news thread."); jvnews = new BlogReader(me); showNews.setVisible(true); - Cache.log.debug("Completed news thread."); + jalview.bin.Console.debug("Completed news thread."); } }).start(); } public void getIdentifiersOrgData() { - // Thread off the identifiers fetcher - new Thread(new Runnable() - { - @Override - public void run() + if (Cache.getProperty("NOIDENTIFIERSSERVICE") == null) + {// Thread off the identifiers fetcher + new Thread(new Runnable() { - Cache.log.debug("Downloading data from identifiers.org"); - try - { - UrlDownloadClient.download(IdOrgSettings.getUrl(), - IdOrgSettings.getDownloadLocation()); - } catch (IOException e) + @Override + public void run() { - Cache.log.debug("Exception downloading identifiers.org data" - + e.getMessage()); + jalview.bin.Console + .debug("Downloading data from identifiers.org"); + try + { + UrlDownloadClient.download(IdOrgSettings.getUrl(), + IdOrgSettings.getDownloadLocation()); + } catch (IOException e) + { + jalview.bin.Console + .debug("Exception downloading identifiers.org data" + + e.getMessage()); + } } - } - }).start(); - + }).start(); + ; + } } @Override @@ -621,7 +692,7 @@ public class Desktop extends jalview.jbgui.GDesktop void showNews(boolean visible) { - Cache.log.debug((visible ? "Showing" : "Hiding") + " news."); + jalview.bin.Console.debug((visible ? "Showing" : "Hiding") + " news."); showNews.setSelected(visible); if (visible && !jvnews.isVisible()) { @@ -655,10 +726,8 @@ public class Desktop extends jalview.jbgui.GDesktop Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); String x = Cache.getProperty(windowName + "SCREEN_X"); String y = Cache.getProperty(windowName + "SCREEN_Y"); - String width = Cache - .getProperty(windowName + "SCREEN_WIDTH"); - String height = Cache - .getProperty(windowName + "SCREEN_HEIGHT"); + String width = Cache.getProperty(windowName + "SCREEN_WIDTH"); + String height = Cache.getProperty(windowName + "SCREEN_HEIGHT"); if ((x != null) && (y != null) && (width != null) && (height != null)) { int ix = Integer.parseInt(x), iy = Integer.parseInt(y), @@ -668,10 +737,10 @@ public class Desktop extends jalview.jbgui.GDesktop // attempt #1 - try to cope with change in screen geometry - this // version doesn't preserve original jv aspect ratio. // take ratio of current screen size vs original screen size. - double sw = ((1f * screenSize.width) / (1f * Integer.parseInt( - Cache.getProperty("SCREENGEOMETRY_WIDTH")))); - double sh = ((1f * screenSize.height) / (1f * Integer.parseInt( - Cache.getProperty("SCREENGEOMETRY_HEIGHT")))); + double sw = ((1f * screenSize.width) / (1f * Integer + .parseInt(Cache.getProperty("SCREENGEOMETRY_WIDTH")))); + double sh = ((1f * screenSize.height) / (1f * Integer + .parseInt(Cache.getProperty("SCREENGEOMETRY_HEIGHT")))); // rescale the bounds depending upon the current screen geometry. ix = (int) (ix * sw); iw = (int) (iw * sw); @@ -679,17 +748,17 @@ public class Desktop extends jalview.jbgui.GDesktop ih = (int) (ih * sh); while (ix >= screenSize.width) { - Cache.log.debug( + jalview.bin.Console.debug( "Window geometry location recall error: shifting horizontal to within screenbounds."); ix -= screenSize.width; } while (iy >= screenSize.height) { - Cache.log.debug( + jalview.bin.Console.debug( "Window geometry location recall error: shifting vertical to within screenbounds."); iy -= screenSize.height; } - Cache.log.debug( + jalview.bin.Console.debug( "Got last known dimensions for " + windowName + ": x:" + ix + " y:" + iy + " width:" + iw + " height:" + ih); } @@ -879,8 +948,8 @@ public class Desktop extends jalview.jbgui.GDesktop } /* - * add an entry for the new frame in the Window menu - * (and remove it when the frame is closed) + * add an entry for the new frame in the Window menu (and remove it when the + * frame is closed) */ final JMenuItem menuItem = new JMenuItem(title); frame.addInternalFrameListener(new InternalFrameAdapter() @@ -905,8 +974,7 @@ public class Desktop extends jalview.jbgui.GDesktop PaintRefresher.RemoveComponent(frame); /* - * defensive check to prevent frames being - * added half off the window + * defensive check to prevent frames being added half off the window */ if (openFrameCount > 0) { @@ -935,7 +1003,7 @@ public class Desktop extends jalview.jbgui.GDesktop frame.setIcon(false); } catch (java.beans.PropertyVetoException ex) { - // System.err.println(ex.toString()); + } } }); @@ -955,15 +1023,15 @@ public class Desktop extends jalview.jbgui.GDesktop { } catch (java.lang.ClassCastException cex) { - Cache.log.warn( - "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869", + jalview.bin.Console.warn( + "Squashed a possible GUI implementation error. If you can recreate this, please look at https://issues.jalview.org/browse/JAL-869", cex); } } /** - * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close the - * window + * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close + * the window * * @param frame */ @@ -1103,8 +1171,9 @@ public class Desktop extends jalview.jbgui.GDesktop public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport) { String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT"); - JalviewFileChooser chooser = JalviewFileChooser - .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat, BackupFiles.getEnabled()); + JalviewFileChooser chooser = JalviewFileChooser.forRead( + Cache.getProperty("LAST_DIRECTORY"), fileFormat, + BackupFiles.getEnabled()); chooser.setFileView(new JalviewFileView()); chooser.setDialogTitle( @@ -1123,8 +1192,8 @@ public class Desktop extends jalview.jbgui.GDesktop /* * Call IdentifyFile to verify the file contains what its extension implies. - * Skip this step for dynamically added file formats, because - * IdentifyFile does not know how to recognise them. + * Skip this step for dynamically added file formats, because IdentifyFile does + * not know how to recognise them. */ if (FileFormats.getInstance().isIdentifiable(format)) { @@ -1162,12 +1231,11 @@ public class Desktop extends jalview.jbgui.GDesktop panel.add(label); /* - * the URL to fetch is - * Java: an editable combobox with history - * JS: (pending JAL-3038) a plain text field + * the URL to fetch is input in Java: an editable combobox with history JS: + * (pending JAL-3038) a plain text field */ JComponent history; - String urlBase = "http://www."; + String urlBase = "https://www."; if (Platform.isJS()) { history = new JTextField(urlBase, 35); @@ -1205,10 +1273,10 @@ public class Desktop extends jalview.jbgui.GDesktop @SuppressWarnings("unchecked") String url = (history instanceof JTextField ? ((JTextField) history).getText() - : ((JComboBox) history).getSelectedItem() - .toString()); + : ((JComboBox) history).getEditor().getItem() + .toString().trim()); - if (url.toLowerCase().endsWith(".jar")) + if (url.toLowerCase(Locale.ROOT).endsWith(".jar")) { if (viewport != null) { @@ -1290,10 +1358,8 @@ public class Desktop extends jalview.jbgui.GDesktop public void quit() { Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); - Cache.setProperty("SCREENGEOMETRY_WIDTH", - screen.width + ""); - Cache.setProperty("SCREENGEOMETRY_HEIGHT", - screen.height + ""); + Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + ""); + Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + ""); storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y, getWidth(), getHeight())); @@ -1324,8 +1390,8 @@ public class Desktop extends jalview.jbgui.GDesktop private void storeLastKnownDimensions(String string, Rectangle jc) { - Cache.log.debug("Storing last known dimensions for " - + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width + jalview.bin.Console.debug("Storing last known dimensions for " + string + + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width + " height:" + jc.height); Cache.setProperty(string + "SCREEN_X", jc.x + ""); @@ -1363,7 +1429,8 @@ public class Desktop extends jalview.jbgui.GDesktop public String getAboutMessage() { StringBuilder message = new StringBuilder(1024); - message.append("

Version: ") + message.append("
") + .append("

Version: ") .append(Cache.getProperty("VERSION")).append("

") .append("Built: ") .append(Cache.getDefault("BUILD_DATE", "unknown")) @@ -1379,7 +1446,7 @@ public class Desktop extends jalview.jbgui.GDesktop else if (!latestVersion.equals(Cache.getProperty("VERSION"))) { boolean red = false; - if (Cache.getProperty("VERSION").toLowerCase() + if (Cache.getProperty("VERSION").toLowerCase(Locale.ROOT) .indexOf("automated build") == -1) { red = true; @@ -1392,7 +1459,7 @@ public class Desktop extends jalview.jbgui.GDesktop .append(Cache.getDefault("LATEST_VERSION", "..Checking..")) .append(" is available for download from ") .append(Cache.getDefault("www.jalview.org", - "http://www.jalview.org")) + "https://www.jalview.org")) .append(" !!"); if (red) { @@ -1403,6 +1470,8 @@ public class Desktop extends jalview.jbgui.GDesktop message.append(Cache.getDefault("AUTHORFNAMES", DEFAULT_AUTHORS)); message.append(CITATION); + message.append("
"); + return message.toString(); } @@ -1416,7 +1485,7 @@ public class Desktop extends jalview.jbgui.GDesktop { if (Platform.isJS()) { - BrowserLauncher.openURL("http://www.jalview.org/help.html"); + BrowserLauncher.openURL("https://www.jalview.org/help.html"); } else /** @@ -1489,17 +1558,16 @@ public class Desktop extends jalview.jbgui.GDesktop protected void garbageCollect_actionPerformed(ActionEvent e) { // We simply collect the garbage - Cache.log.debug("Collecting garbage..."); + jalview.bin.Console.debug("Collecting garbage..."); System.gc(); - Cache.log.debug("Finished garbage collection."); + jalview.bin.Console.debug("Finished garbage collection."); } /* * (non-Javadoc) * - * @see - * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent - * ) + * @see jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event. + * ActionEvent ) */ @Override protected void showMemusage_actionPerformed(ActionEvent e) @@ -1625,7 +1693,7 @@ public class Desktop extends jalview.jbgui.GDesktop @Override protected void preferences_actionPerformed(ActionEvent e) { - new Preferences(); + Preferences.openPreferences(); } /** @@ -1681,16 +1749,17 @@ public class Desktop extends jalview.jbgui.GDesktop setProgressBar(MessageManager.formatMessage( "label.saving_jalview_project", new Object[] { chosenFile.getName() }), chosenFile.hashCode()); - Cache.setProperty("LAST_DIRECTORY", - chosenFile.getParent()); + Cache.setProperty("LAST_DIRECTORY", chosenFile.getParent()); // TODO catch and handle errors for savestate // TODO prevent user from messing with the Desktop whilst we're saving try { - boolean doBackup = BackupFiles.getEnabled(); - BackupFiles backupfiles = doBackup ? new BackupFiles(chosenFile) : null; + boolean doBackup = BackupFiles.getEnabled(); + BackupFiles backupfiles = doBackup ? new BackupFiles(chosenFile) + : null; - new Jalview2XML().saveState(doBackup ? backupfiles.getTempFile() : chosenFile); + new Jalview2XML().saveState( + doBackup ? backupfiles.getTempFile() : chosenFile); if (doBackup) { @@ -1703,7 +1772,7 @@ public class Desktop extends jalview.jbgui.GDesktop + chosenFile.getName(), oom); } catch (Exception ex) { - Cache.log.error("Problems whilst trying to save to " + jalview.bin.Console.error("Problems whilst trying to save to " + chosenFile.getName(), ex); JvOptionPane.showMessageDialog(me, MessageManager.formatMessage( @@ -1716,7 +1785,7 @@ public class Desktop extends jalview.jbgui.GDesktop setProgressBar(null, chosenFile.hashCode()); } }).start(); - } + } } @Override @@ -1747,8 +1816,10 @@ public class Desktop extends jalview.jbgui.GDesktop "Jalview Project (old)" }; JalviewFileChooser chooser = new JalviewFileChooser( Cache.getProperty("LAST_DIRECTORY"), suffix, desc, - "Jalview Project", true, BackupFiles.getEnabled()); // last two booleans: allFiles, - // allowBackupFiles + "Jalview Project", true, BackupFiles.getEnabled()); // last two + // booleans: + // allFiles, + // allowBackupFiles chooser.setFileView(new JalviewFileView()); chooser.setDialogTitle(MessageManager.getString("label.restore_state")); chooser.setResponseHandler(0, new Runnable() @@ -1765,29 +1836,30 @@ public class Desktop extends jalview.jbgui.GDesktop @Override public void run() { - try + try { - new Jalview2XML().loadJalviewAlign(choice); + new Jalview2XML().loadJalviewAlign(selectedFile); } catch (OutOfMemoryError oom) - { - new OOMWarning("Whilst loading project from " + choice, oom); - } catch (Exception ex) - { - Cache.log.error( - "Problems whilst loading project from " + choice, ex); - JvOptionPane.showMessageDialog(Desktop.desktop, - MessageManager.formatMessage( - "label.error_whilst_loading_project_from", - new Object[] - { choice }), - MessageManager.getString("label.couldnt_load_project"), - JvOptionPane.WARNING_MESSAGE); - } + { + new OOMWarning("Whilst loading project from " + choice, oom); + } catch (Exception ex) + { + jalview.bin.Console.error( + "Problems whilst loading project from " + choice, ex); + JvOptionPane.showMessageDialog(Desktop.desktop, + MessageManager.formatMessage( + "label.error_whilst_loading_project_from", + new Object[] + { choice }), + MessageManager + .getString("label.couldnt_load_project"), + JvOptionPane.WARNING_MESSAGE); + } } - }).start(); + }, "Project Loader").start(); } }); - + chooser.showOpenDialog(this); } @@ -1976,9 +2048,7 @@ public class Desktop extends jalview.jbgui.GDesktop // FIXME: ideally should use UI interface API FeatureSettings viewFeatureSettings = (af.featureSettings != null - && af.featureSettings.isOpen()) - ? af.featureSettings - : null; + && af.featureSettings.isOpen()) ? af.featureSettings : null; Rectangle fsBounds = af.getFeatureSettingsGeometry(); for (int i = 0; i < size; i++) { @@ -1997,9 +2067,8 @@ public class Desktop extends jalview.jbgui.GDesktop } /* - * Restore the view's last exploded frame geometry if known. Multiple - * views from one exploded frame share and restore the same (frame) - * position and size. + * Restore the view's last exploded frame geometry if known. Multiple views from + * one exploded frame share and restore the same (frame) position and size. */ Rectangle geometry = ap.av.getExplodedGeometry(); if (geometry != null) @@ -2011,7 +2080,8 @@ public class Desktop extends jalview.jbgui.GDesktop addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); - // and materialise a new feature settings dialog instance for the new alignframe + // and materialise a new feature settings dialog instance for the new + // alignframe // (closes the old as if 'OK' was pressed) if (ap == af.alignPanel && newaf.featureSettings != null && newaf.featureSettings.isOpen() @@ -2029,9 +2099,9 @@ public class Desktop extends jalview.jbgui.GDesktop /** * Gather expanded views (separate AlignFrame's) with the same sequence set - * identifier back in to this frame as additional views, and close the expanded - * views. Note the expanded frames may themselves have multiple views. We take - * the lot. + * identifier back in to this frame as additional views, and close the + * expanded views. Note the expanded frames may themselves have multiple + * views. We take the lot. * * @param source */ @@ -2083,11 +2153,11 @@ public class Desktop extends jalview.jbgui.GDesktop } // refresh the feature setting UI for the source frame if it exists - if (source.featureSettings != null - && source.featureSettings.isOpen()) + if (source.featureSettings != null && source.featureSettings.isOpen()) { source.showFeatureSettingsUI(); } + } public JInternalFrame[] getAllFrames() @@ -2189,12 +2259,12 @@ public class Desktop extends jalview.jbgui.GDesktop /** * Proxy class for JDesktopPane which optionally displays the current memory - * usage and highlights the desktop area with a red bar if free memory runs low. + * usage and highlights the desktop area with a red bar if free memory runs + * low. * * @author AMW */ - public class MyDesktopPane extends JDesktopPane - implements Runnable + public class MyDesktopPane extends JDesktopPane implements Runnable { private static final float ONE_MB = 1048576f; @@ -2281,6 +2351,9 @@ public class Desktop extends jalview.jbgui.GDesktop 10, getHeight() - fm.getHeight()); } } + + // output debug scale message. Important for jalview.bin.HiDPISettingTest2 + Desktop.debugScaleMessage(Desktop.getDesktop().getGraphics()); } } @@ -2377,7 +2450,7 @@ public class Desktop extends jalview.jbgui.GDesktop openGroovyConsole(); } catch (Exception ex) { - Cache.log.error("Groovy Shell Creation failed.", ex); + jalview.bin.Console.error("Groovy Shell Creation failed.", ex); JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager.getString("label.couldnt_create_groovy_shell"), @@ -2399,9 +2472,9 @@ public class Desktop extends jalview.jbgui.GDesktop /* * We allow only one console at a time, so that AlignFrame menu option - * 'Calculate | Run Groovy script' is unambiguous. - * Disable 'Groovy Console', and enable 'Run script', when the console is - * opened, and the reverse when it is closed + * 'Calculate | Run Groovy script' is unambiguous. Disable 'Groovy Console', and + * enable 'Run script', when the console is opened, and the reverse when it is + * closed */ Window window = (Window) groovyConsole.getFrame(); window.addWindowListener(new WindowAdapter() @@ -2424,21 +2497,24 @@ public class Desktop extends jalview.jbgui.GDesktop ((Window) groovyConsole.getFrame()).setVisible(true); /* - * if we got this far, enable 'Run Groovy' in AlignFrame menus - * and disable opening a second console + * if we got this far, enable 'Run Groovy' in AlignFrame menus and disable + * opening a second console */ enableExecuteGroovy(true); } /** - * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this binding - * when opened + * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this + * binding when opened */ protected void addQuitHandler() { - getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) - .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, - jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()), + getRootPane() + .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( + KeyStroke + .getKeyStroke(KeyEvent.VK_Q, + jalview.util.ShortcutKeyMaskExWrapper + .getMenuShortcutKeyMaskEx()), "Quit"); getRootPane().getActionMap().put("Quit", new AbstractAction() { @@ -2459,8 +2535,8 @@ public class Desktop extends jalview.jbgui.GDesktop public void enableExecuteGroovy(boolean enabled) { /* - * disable opening a second Groovy console - * (or re-enable when the console is closed) + * disable opening a second Groovy console (or re-enable when the console is + * closed) */ groovyShell.setEnabled(!enabled); @@ -2489,8 +2565,6 @@ public class Desktop extends jalview.jbgui.GDesktop @Override public void setProgressBar(String message, long id) { - Platform.timeCheck("Desktop " + message, Platform.TIME_MARK); - if (progressBars == null) { progressBars = new Hashtable<>(); @@ -2567,8 +2641,9 @@ public class Desktop extends jalview.jbgui.GDesktop } /** - * This will return the first AlignFrame holding the given viewport instance. It - * will break if there are more than one AlignFrames viewing a particular av. + * This will return the first AlignFrame holding the given viewport instance. + * It will break if there are more than one AlignFrames viewing a particular + * av. * * @param viewport * @return alignFrame for viewport @@ -2622,13 +2697,36 @@ public class Desktop extends jalview.jbgui.GDesktop this.inBatchMode = inBatchMode; } + /** + * start service discovery and wait till it is done + */ public void startServiceDiscovery() { startServiceDiscovery(false); } + /** + * start service discovery threads - blocking or non-blocking + * + * @param blocking + */ public void startServiceDiscovery(boolean blocking) { + startServiceDiscovery(blocking, false); + } + + /** + * start service discovery threads + * + * @param blocking + * - false means call returns immediately + * @param ignore_SHOW_JWS2_SERVICES_preference + * - when true JABA services are discovered regardless of user's JWS2 + * discovery preference setting + */ + public void startServiceDiscovery(boolean blocking, + boolean ignore_SHOW_JWS2_SERVICES_preference) + { boolean alive = true; Thread t0 = null, t1 = null, t2 = null; // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release @@ -2646,7 +2744,8 @@ public class Desktop extends jalview.jbgui.GDesktop (t0 = new Thread(discoverer)).start(); } - if (Cache.getDefault("SHOW_JWS2_SERVICES", true)) + if (ignore_SHOW_JWS2_SERVICES_preference + || Cache.getDefault("SHOW_JWS2_SERVICES", true)) { t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer() .startDiscoverer(changeSupport); @@ -2699,24 +2798,19 @@ public class Desktop extends jalview.jbgui.GDesktop /* * JalviewDialog jd =new JalviewDialog() { * - * @Override protected void cancelPressed() { // TODO - * Auto-generated method stub + * @Override protected void cancelPressed() { // TODO Auto-generated method stub * - * }@Override protected void okPressed() { // TODO - * Auto-generated method stub + * }@Override protected void okPressed() { // TODO Auto-generated method stub * - * }@Override protected void raiseClosed() { // TODO - * Auto-generated method stub + * }@Override protected void raiseClosed() { // TODO Auto-generated method stub * - * } }; jd.initDialogFrame(new - * JLabel("
" + ermsg + + * } }; jd.initDialogFrame(new JLabel("
" + + * ermsg + * "
It may be that you have invalid JABA URLs in your web service preferences," * + " or mis-configured HTTP proxy settings.
" + - * "Check the Connections and Web services tab of the" - * + - * " Tools->Preferences dialog box to change them.
" - * ), true, true, "Web Service Configuration Problem", 450, - * 400); + * "Check the Connections and Web services tab of the" + + * " Tools->Preferences dialog box to change them.
" ), + * true, true, "Web Service Configuration Problem", 450, 400); * * jd.waitForInput(); */ @@ -2738,7 +2832,7 @@ public class Desktop extends jalview.jbgui.GDesktop } else { - Cache.log.error( + jalview.bin.Console.error( "Errors reported by JABA discovery service. Check web services preferences.\n" + ermsg); } @@ -2831,15 +2925,8 @@ public class Desktop extends jalview.jbgui.GDesktop { if (url != null) { - if (Cache.log != null) - { - Cache.log.error("Couldn't handle string " + url + " as a URL."); - } - else - { - System.err.println( - "Couldn't handle string " + url + " as a URL."); - } + jalview.bin.Console + .error("Couldn't handle string " + url + " as a URL."); } // ignore any exceptions due to dud links. } @@ -2894,7 +2981,8 @@ public class Desktop extends jalview.jbgui.GDesktop SwingUtilities.invokeAndWait(prompter); } catch (Exception q) { - Cache.log.warn("Unexpected Exception in dialog thread.", q); + jalview.bin.Console.warn("Unexpected Exception in dialog thread.", + q); } } }); @@ -2933,7 +3021,7 @@ public class Desktop extends jalview.jbgui.GDesktop public void exportImage(Graphics g) throws Exception { paintAll(g); - Cache.log.info("Successfully written snapshot to file " + jalview.bin.Console.info("Successfully written snapshot to file " + of.getAbsolutePath()); } }; @@ -2945,8 +3033,8 @@ public class Desktop extends jalview.jbgui.GDesktop /** * Explode the views in the given SplitFrame into separate SplitFrame windows. - * This respects (remembers) any previous 'exploded geometry' i.e. the size and - * location last time the view was expanded (if any). However it does not + * This respects (remembers) any previous 'exploded geometry' i.e. the size + * and location last time the view was expanded (if any). However it does not * remember the split pane divider location - this is set to match the * 'exploding' frame. * @@ -2967,16 +3055,15 @@ public class Desktop extends jalview.jbgui.GDesktop } /* - * Processing in reverse order works, forwards order leaves the first panels - * not visible. I don't know why! + * Processing in reverse order works, forwards order leaves the first panels not + * visible. I don't know why! */ for (int i = viewCount - 1; i >= 0; i--) { /* - * Make new top and bottom frames. These take over the respective - * AlignmentPanel objects, including their AlignmentViewports, so the - * cdna/protein relationships between the viewports is carried over to the - * new split frames. + * Make new top and bottom frames. These take over the respective AlignmentPanel + * objects, including their AlignmentViewports, so the cdna/protein + * relationships between the viewports is carried over to the new split frames. * * explodedGeometry holds the (x, y) position of the previously exploded * SplitFrame, and the (width, height) of the AlignFrame component @@ -3015,8 +3102,8 @@ public class Desktop extends jalview.jbgui.GDesktop } /* - * Clear references to the panels (now relocated in the new SplitFrames) - * before closing the old SplitFrame. + * Clear references to the panels (now relocated in the new SplitFrames) before + * closing the old SplitFrame. */ topPanels.clear(); bottomPanels.clear(); @@ -3117,26 +3204,6 @@ public class Desktop extends jalview.jbgui.GDesktop Transferable t) throws Exception { - // BH 2018 changed List to List to allow for File from SwingJS - - // DataFlavor[] flavors = t.getTransferDataFlavors(); - // for (int i = 0; i < flavors.length; i++) { - // if (flavors[i].isFlavorJavaFileListType()) { - // evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - // List list = (List) t.getTransferData(flavors[i]); - // for (int j = 0; j < list.size(); j++) { - // File file = (File) list.get(j); - // byte[] data = getDroppedFileBytes(file); - // fileName.setText(file.getName() + " - " + data.length + " " + - // evt.getLocation()); - // JTextArea target = (JTextArea) ((DropTarget) evt.getSource()).getComponent(); - // target.setText(new String(data)); - // } - // dtde.dropComplete(true); - // return; - // } - // - DataFlavor uriListFlavor = new DataFlavor( "text/uri-list;class=java.lang.String"), urlFlavour = null; try @@ -3145,7 +3212,8 @@ public class Desktop extends jalview.jbgui.GDesktop "application/x-java-url; class=java.net.URL"); } catch (ClassNotFoundException cfe) { - Cache.log.debug("Couldn't instantiate the URL dataflavor.", cfe); + jalview.bin.Console.debug("Couldn't instantiate the URL dataflavor.", + cfe); } if (urlFlavour != null && t.isDataFlavorSupported(urlFlavour)) @@ -3160,7 +3228,7 @@ public class Desktop extends jalview.jbgui.GDesktop { protocols.add(DataSourceType.URL); files.add(url.toString()); - Cache.log.debug("Drop handled as URL dataflavor " + jalview.bin.Console.debug("Drop handled as URL dataflavor " + files.get(files.size() - 1)); return; } @@ -3174,13 +3242,13 @@ public class Desktop extends jalview.jbgui.GDesktop } } catch (Throwable ex) { - Cache.log.debug("URL drop handler failed.", ex); + jalview.bin.Console.debug("URL drop handler failed.", ex); } } if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { // Works on Windows and MacOSX - Cache.log.debug("Drop handled as javaFileListFlavor"); + jalview.bin.Console.debug("Drop handled as javaFileListFlavor"); for (Object file : (List) t .getTransferData(DataFlavor.javaFileListFlavor)) { @@ -3195,14 +3263,15 @@ public class Desktop extends jalview.jbgui.GDesktop String data = null; if (t.isDataFlavorSupported(uriListFlavor)) { - Cache.log.debug("Drop handled as uriListFlavor"); + jalview.bin.Console.debug("Drop handled as uriListFlavor"); // This is used by Unix drag system data = (String) t.getTransferData(uriListFlavor); } if (data == null) { // fallback to text: workaround - on OSX where there's a JVM bug - Cache.log.debug("standard URIListFlavor failed. Trying text"); + jalview.bin.Console + .debug("standard URIListFlavor failed. Trying text"); // try text fallback DataFlavor textDf = new DataFlavor( "text/plain;class=java.lang.String"); @@ -3211,7 +3280,7 @@ public class Desktop extends jalview.jbgui.GDesktop data = (String) t.getTransferData(textDf); } - Cache.log.debug("Plain text drop content returned " + jalview.bin.Console.debug("Plain text drop content returned " + (data == null ? "Null - failed" : data)); } @@ -3219,7 +3288,7 @@ public class Desktop extends jalview.jbgui.GDesktop { while (protocols.size() < files.size()) { - Cache.log.debug("Adding missing FILE protocol for " + jalview.bin.Console.debug("Adding missing FILE protocol for " + files.get(protocols.size())); protocols.add(DataSourceType.FILE); } @@ -3234,7 +3303,7 @@ public class Desktop extends jalview.jbgui.GDesktop continue; } java.net.URI uri = new java.net.URI(s); - if (uri.getScheme().toLowerCase().startsWith("http")) + if (uri.getScheme().toLowerCase(Locale.ROOT).startsWith("http")) { protocols.add(DataSourceType.URL); files.add(uri.toString()); @@ -3249,7 +3318,7 @@ public class Desktop extends jalview.jbgui.GDesktop } } - if (Cache.log.isDebugEnabled()) + if (jalview.bin.Console.isDebugEnabled()) { if (data == null || !added) { @@ -3257,39 +3326,41 @@ public class Desktop extends jalview.jbgui.GDesktop if (t.getTransferDataFlavors() != null && t.getTransferDataFlavors().length > 0) { - Cache.log.debug( + jalview.bin.Console.debug( "Couldn't resolve drop data. Here are the supported flavors:"); for (DataFlavor fl : t.getTransferDataFlavors()) { - Cache.log.debug( + jalview.bin.Console.debug( "Supported transfer dataflavor: " + fl.toString()); Object df = t.getTransferData(fl); if (df != null) { - Cache.log.debug("Retrieves: " + df); + jalview.bin.Console.debug("Retrieves: " + df); } else { - Cache.log.debug("Retrieved nothing"); + jalview.bin.Console.debug("Retrieved nothing"); } } } else { - Cache.log.debug("Couldn't resolve dataflavor for drop: " - + t.toString()); + jalview.bin.Console + .debug("Couldn't resolve dataflavor for drop: " + + t.toString()); } } } } if (Platform.isWindowsAndNotJS()) { - Cache.log.debug("Scanning dropped content for Windows Link Files"); + jalview.bin.Console + .debug("Scanning dropped content for Windows Link Files"); // resolve any .lnk files in the file drop for (int f = 0; f < files.size(); f++) { - String source = files.get(f).toString().toLowerCase(); + String source = files.get(f).toString().toLowerCase(Locale.ROOT); if (protocols.get(f).equals(DataSourceType.FILE) && (source.endsWith(".lnk") || source.endsWith(".url") || source.endsWith(".site"))) @@ -3300,16 +3371,16 @@ public class Desktop extends jalview.jbgui.GDesktop File lf = (obj instanceof File ? (File) obj : new File((String) obj)); // process link file to get a URL - Cache.log.debug("Found potential link file: " + lf); + jalview.bin.Console.debug("Found potential link file: " + lf); WindowsShortcut wscfile = new WindowsShortcut(lf); String fullname = wscfile.getRealFilename(); protocols.set(f, FormatAdapter.checkProtocol(fullname)); files.set(f, fullname); - Cache.log.debug("Parsed real filename " + fullname + jalview.bin.Console.debug("Parsed real filename " + fullname + " to extract protocol: " + protocols.get(f)); } catch (Exception ex) { - Cache.log.error( + jalview.bin.Console.error( "Couldn't parse " + files.get(f) + " as a link file.", ex); } @@ -3329,10 +3400,10 @@ public class Desktop extends jalview.jbgui.GDesktop } /** - * Answers a (possibly empty) list of any structure viewer frames (currently for - * either Jmol or Chimera) which are currently open. This may optionally be - * restricted to viewers of a specified class, or viewers linked to a specified - * alignment panel. + * Answers a (possibly empty) list of any structure viewer frames (currently + * for either Jmol or Chimera) which are currently open. This may optionally + * be restricted to viewers of a specified class, or viewers linked to a + * specified alignment panel. * * @param apanel * if not null, only return viewers linked to this panel @@ -3364,4 +3435,37 @@ public class Desktop extends jalview.jbgui.GDesktop } return result; } + + public static final String debugScaleMessage = "Desktop graphics transform scale="; + + private static boolean debugScaleMessageDone = false; + + public static void debugScaleMessage(Graphics g) + { + if (debugScaleMessageDone) + { + return; + } + // output used by tests to check HiDPI scaling settings in action + try + { + Graphics2D gg = (Graphics2D) g; + if (gg != null) + { + AffineTransform t = gg.getTransform(); + double scaleX = t.getScaleX(); + double scaleY = t.getScaleY(); + jalview.bin.Console.debug(debugScaleMessage + scaleX + " (X)"); + jalview.bin.Console.debug(debugScaleMessage + scaleY + " (Y)"); + debugScaleMessageDone = true; + } + else + { + jalview.bin.Console.debug("Desktop graphics null"); + } + } catch (Exception e) + { + jalview.bin.Console.debug(Cache.getStackTraceString(e)); + } + } }