*/
package jalview.gui;
+import java.util.Locale;
import java.awt.BorderLayout;
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;
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.Vector;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.Semaphore;
import javax.swing.AbstractAction;
import jalview.io.IdentifyFile;
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
+import jalview.jbgui.APQHandlers;
import jalview.jbgui.GDesktop;
import jalview.jbgui.GSplitFrame;
import jalview.jbgui.GStructureViewer;
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;
import jalview.util.UrlConstants;
import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.WSDiscovererI;
import jalview.ws.params.ParamManager;
import jalview.ws.utils.UrlDownloadClient;
StructureSelectionManagerProvider, ApplicationSingletonI
{
- private static final String CITATION = "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
- + "<br><br>For help, see the FAQ at <a href=\"http://www.jalview.org/faq\">www.jalview.org/faq</a> and/or join the jalview-discuss@jalview.org mailing list"
- + "<br><br>If you use Jalview, please cite:"
- + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
- + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
- + "<br>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(
+ "<br><br>Jalview is free software released under GPLv3.<br><br>Development is managed by The Barton Group, University of Dundee, Scotland, UK.");
+ if (logo)
+ {
+ sb.append("<br>");
+ }
+ sb.append(bg_logo_url == null ? "" : "<img alt=\"Barton Group logo\" src=\"" + bg_logo_url.toString() + "\">");
+ sb.append(uod_logo_url == null ? ""
+ : " <img alt=\"University of Dundee shield\" src=\"" + uod_logo_url.toString() + "\">");
+ sb.append(
+ "<br><br>For help, see <a href=\"https://www.jalview.org/faq\">www.jalview.org/faq</a> and join <a href=\"https://discourse.jalview.org\">discourse.jalview.org</a>");
+ sb.append("<br><br>If you use Jalview, please cite:"
+ + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
+ + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
+ + "<br>Bioinformatics <a href=\"https://doi.org/10.1093/bioinformatics/btp033\">doi: 10.1093/bioinformatics/btp033</a>");
+ CITATION = sb.toString();
+ }
private static final String DEFAULT_AUTHORS = "The Jalview Authors (See AUTHORS file for current list)";
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<String, FileWriter> savingFiles = new HashMap<String, FileWriter>();
+ @SuppressWarnings("deprecation")
private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
+ public static boolean nosplash = false;
+
/**
* news reader - null if it was never started.
*/
* @param listener
* @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
*/
+ @Deprecated
public void addJalviewPropertyChangeListener(
PropertyChangeListener listener)
{
* @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
* java.beans.PropertyChangeListener)
*/
+ @Deprecated
public void addJalviewPropertyChangeListener(String propertyName,
PropertyChangeListener listener)
{
* @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
* java.beans.PropertyChangeListener)
*/
+ @Deprecated
public void removeJalviewPropertyChangeListener(String propertyName,
PropertyChangeListener listener)
{
*/
private Desktop()
{
- Cache.initLogger();
+ super();
try
{
/**
*/
doConfigureStructurePrefs();
- setTitle("Jalview " + Cache.getProperty("VERSION"));
- /*
- if (!Platform.isAMac())
- {
- // this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- }
- else
+ setTitle(ChannelProperties.getProperty("app_name") + " " + Cache.getProperty("VERSION"));
+
+ /**
+ * 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())
+ {
+ if (LaunchUtils.getJavaVersion() >= 11)
{
- this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+ 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
{
- APQHandlers.setAPQHandlers(this);
- } catch (Throwable t)
- {
- System.out.println("Error setting APQHandlers: " + t.toString());
- // t.printStackTrace();
- }
+ Toolkit xToolkit = Toolkit.getDefaultToolkit();
+ Field[] declaredFields = xToolkit.getClass().getDeclaredFields();
+ Field awtAppClassNameField = null;
- addWindowListener(new WindowAdapter()
- {
+ if (Arrays.stream(declaredFields).anyMatch(f -> f.getName().equals("awtAppClassName"))) {
+ awtAppClassNameField = xToolkit.getClass().getDeclaredField("awtAppClassName");
+ }
- @Override
- public void windowClosing(WindowEvent ev)
+ String title = ChannelProperties.getProperty("app_name");
+ if (awtAppClassNameField != null) {
+ awtAppClassNameField.setAccessible(true);
+ awtAppClassNameField.set(xToolkit, title);
+ }
+ else
{
- quit();
+ 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));
+ }
+ }
+
+ /**
+ * APQHandlers sets handlers for About, Preferences and Quit actions peculiar to
+ * macOS's application menu. APQHandlers will check to see if a handler is
+ * supported before setting it.
+ */
+ try {
+ APQHandlers.setAPQHandlers(this);
+ } catch (Exception e) {
+ System.out.println("Cannot set APQHandlers");
+ // e.printStackTrace();
+ } catch (Throwable t) {
+ jalview.bin.Console.warn("Error setting APQHandlers: " + t.toString());
+ jalview.bin.Console.trace(Cache.getStackTraceString(t));
+ }
+
+ setIconImages(ChannelProperties.getIconList());
+
+ addWindowListener(new WindowAdapter() {
+
+ @Override
+ public void windowClosing(WindowEvent ev) {
+ quit();
+ }
+ });
boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", false);
getContentPane().add(desktopPane, BorderLayout.CENTER);
desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
+
// This line prevents Windows Look&Feel resizing all new windows to
// maximum
// if previous window was maximised
setBounds(xPos, yPos, 900, 650);
}
- getIdentifiersOrgData();
-
if (!Platform.isJS())
/**
* Java only
jconsole.setHeader(Cache.getVersionDetailsForConsole());
showConsole(showjconsole);
- showNews.setVisible(false);
+ showNews.setVisible(false); // not sure if we should only do this for interactive session?
experimentalFeatures.setSelected(showExperimental());
- checkURLLinks();
+ getIdentifiersOrgData();
- // Spawn a thread that shows the splashscreen
-
- SwingUtilities.invokeLater(new Runnable()
+ if (Jalview.isInteractive())
{
- @Override
- public void run()
- {
- new SplashScreen(true);
+ // disabled for SeqCanvasTest
+ checkURLLinks();
+
+ // Spawn a thread that shows the splashscreen
+ if (!nosplash) {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ new SplashScreen(true);
+ }
+ });
}
- });
- // 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()
+ // Thread off a new instance of the file chooser - this reduces the
+ // time
+ // it
+ // takes to open it later on.
+ new Thread(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 propertyChange(PropertyChangeEvent evt)
+ @Override
+ public void run()
+ {
+ jalview.bin.Console.debug("Filechooser init thread started.");
+ String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+ JalviewFileChooser.forRead(
+ Cache.getProperty("LAST_DIRECTORY"), fileFormat);
+ jalview.bin.Console.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)
+ {
+ jalview.bin.Console.debug("Firing service changed event for "
+ + evt.getNewValue());
+ JalviewServicesChanged(evt);
+ }
+ });
+ }
}
this.setDropTarget(new java.awt.dnd.DropTarget(desktopPane, this));
showPasteMenu(evt.getX(), evt.getY());
}
}
-
@Override
public void mouseReleased(MouseEvent evt)
{
{
t.printStackTrace();
}
-
}
/**
public void doConfigureStructurePrefs()
{
// configure services
- StructureSelectionManager ssm = StructureSelectionManager
- .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.setSecStructServices(
- Cache.getDefault(Preferences.USE_RNAVIEW, true));
- }
- else
- {
+ StructureSelectionManager ssm = StructureSelectionManager.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));
+ // JAL-3915 - RNAView is no longer an option so this has no effect
+ ssm.setSecStructServices(Cache.getDefault(Preferences.USE_RNAVIEW, false));
+ } else {
ssm.setAddTempFacAnnot(false);
ssm.setProcessSecondaryStructure(false);
ssm.setSecStructServices(false);
}
}
- public void checkForNews()
- {
+ public void checkForNews() {
final Desktop me = this;
// Thread off the news reader, in case there are connection problems.
- new Thread(new Runnable()
- {
+ new Thread(new Runnable() {
@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()
- {
- Cache.log.debug("Downloading data from identifiers.org");
- try
- {
- UrlDownloadClient.download(IdOrgSettings.getUrl(),
- IdOrgSettings.getDownloadLocation());
- } catch (IOException e)
+ public void getIdentifiersOrgData() {
+ if (Cache.getProperty("NOIDENTIFIERSSERVICE") == null) {
+ // Thread off the identifiers fetcher
+ new Thread(new Runnable() {
+ @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
- protected void showNews_actionPerformed(ActionEvent e)
- {
+ protected void showNews_actionPerformed(ActionEvent e) {
showNews(showNews.isSelected());
}
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())
{
String y = Cache.getProperty(windowName + "SCREEN_Y");
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),
- iw = Integer.parseInt(width), ih = Integer.parseInt(height);
- if (Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
- {
+ if ((x != null) && (y != null) && (width != null) && (height != null)) {
+ int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer.parseInt(width),
+ ih = Integer.parseInt(height);
+ if (Cache.getProperty("SCREENGEOMETRY_WIDTH") != null) {
// 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);
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);
}
}
}
-// /**
-// * Add an internal frame to the Jalview desktop that is allowed to be resized,
-// * has a minimum size of 300px and might or might not be visible
-// *
-// * @param frame
-// * Frame to show
-// * @param title
-// * Visible Title
-// * @param makeVisible
-// * When true, display frame immediately, otherwise, caller must call
-// * setVisible themselves.
-// * @param w
-// * width
-// * @param h
-// * height
-// */
-// @Deprecated
-// public static synchronized void addInternalFrame(
-// final JInternalFrame frame, String title, boolean makeVisible,
-// int w, int h)
-// {
-// // textbox, web services, sequenceFetcher, featureSettings
-// getInstance().addFrame(frame, title, makeVisible, w, h,
-// FRAME_ALLOW_RESIZE, FRAME_SET_MIN_SIZE_300);
-// }
-//
-// /**
-// * Add an internal frame to the Jalview desktop that is visible, has a minimum
-// * size of 300px, and may or may not be resizable
-// *
-// * @param frame
-// * Frame to show
-// * @param title
-// * Visible Title
-// * @param w
-// * width
-// * @param h
-// * height
-// * @param resizable
-// * Allow resize
-// */
-// @Deprecated
-// public static synchronized void addInternalFrame(
-// final JInternalFrame frame, String title, int w, int h,
-// boolean resizable)
-// {
-// // annotation, font, calculation, user-defined colors
-// getInstance().addFrame(frame, title, FRAME_MAKE_VISIBLE, w, h,
-// resizable, FRAME_SET_MIN_SIZE_300);
-// }
+
/**
* Adds and opens the given frame to the desktop that is visible, allowed to
final JInternalFrame frame, String title, int w, int h)
{
// 58 classes
- getInstance().addFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, w, h,
+
+ addInternalFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, w, h,
FRAME_ALLOW_RESIZE, FRAME_SET_MIN_SIZE_300);
}
final JInternalFrame frame, String title, boolean makeVisible,
int w, int h, boolean resizable, boolean ignoreMinSize)
{
- // 15 classes
- getInstance().addFrame(frame, title, makeVisible, w, h, resizable,
+ // 15 classes call this method directly.
+
+
+ // 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)
+ {
+ frame.setSize(w, h);
+ }
+ if (getInstance() != null)
+ getInstance().addFrame(frame, makeVisible, resizable,
ignoreMinSize);
}
public final static boolean FRAME_ALLOW_ANY_SIZE = true;
public final static boolean FRAME_SET_MIN_SIZE_300 = false;
-
- private void addFrame(JInternalFrame frame, String title,
- boolean makeVisible, int w, int h, boolean resizable,
+
+ private void addFrame(JInternalFrame frame,
+ boolean makeVisible, 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)
- {
- frame.setSize(w, h);
- }
- // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
- // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
- // IF JALVIEW IS RUNNING HEADLESS
- // ///////////////////////////////////////////////
- if (Jalview.isHeadlessMode())
- {
- return;
- }
openFrameCount++;
+
+ boolean isEmbedded = (Platform.getEmbeddedAttribute(frame, "id") != null);
+ boolean hasEmbeddedSize = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
+ // Web page embedding allows us to ignore minimum size
+ ignoreMinSize |= hasEmbeddedSize;
+
if (!ignoreMinSize)
{
- frame.setMinimumSize(
- new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
// Set default dimension for Alignment Frame window.
// The Alignment Frame window could be added from a number of places,
{
frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
+ } else {
+ frame.setMinimumSize(
+ new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
+
}
}
frame.setMaximizable(resizable);
frame.setIconifiable(resizable);
frame.setOpaque(Platform.isJS());
- boolean isEmbedded = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
+
if (!isEmbedded && frame.getX() < 1 && frame.getY() < 1)
{
frame.setLocation(xOffset * openFrameCount,
* 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);
+ final JMenuItem menuItem = new JMenuItem(frame.getTitle());
frame.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
} catch (java.beans.PropertyVetoException ex)
{
// System.err.println(ex.toString());
+
}
}
});
{
} 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);
}
}
*/
private static void setKeyBindings(JInternalFrame frame)
{
+ @SuppressWarnings("serial")
final Action closeAction = new AbstractAction()
{
@Override
/*
* set up key bindings for Ctrl-W and Cmd-W, with the same (Close) action
*/
- KeyStroke ctrlWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W,
- InputEvent.CTRL_DOWN_MASK);
- KeyStroke cmdWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W,
- ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx());
+ KeyStroke ctrlWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK);
+ KeyStroke cmdWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, Platform.SHORTCUT_KEY_MASK);
InputMap inputMap = frame
.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
* 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);
public void run()
{
@SuppressWarnings("unchecked")
- String url = (history instanceof JTextField
- ? ((JTextField) history).getText()
- : ((JComboBox<String>) history).getSelectedItem()
- .toString());
-
- if (url.toLowerCase().endsWith(".jar"))
- {
- if (viewport != null)
- {
- new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
- FileFormat.Jalview);
- }
- else
- {
- new FileLoader().LoadFile(url, DataSourceType.URL,
- FileFormat.Jalview);
+ String url = (history instanceof JTextField ? ((JTextField) history).getText()
+ : ((JComboBox<String>) history).getEditor().getItem().toString().trim());
+
+ if (url.toLowerCase(Locale.ROOT).endsWith(".jar")) {
+ if (viewport != null) {
+ new FileLoader().LoadFile(viewport, url, DataSourceType.URL, FileFormat.Jalview);
+ } else {
+ new FileLoader().LoadFile(url, DataSourceType.URL, FileFormat.Jalview);
}
- }
- else
- {
+ } else {
FileFormatI format = null;
try
{
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 + " height:"
- + jc.height);
+ 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 + "");
Cache.setProperty(string + "SCREEN_Y", jc.y + "");
public String getAboutMessage()
{
StringBuilder message = new StringBuilder(1024);
- message.append("<h1><strong>Version: ")
- .append(Cache.getProperty("VERSION")).append("</strong></h1>")
- .append("<strong>Built: <em>")
- .append(Cache.getDefault("BUILD_DATE", "unknown"))
- .append("</em> from ").append(Cache.getBuildDetailsForSplash())
- .append("</strong>");
+ message.append("<div style=\"font-family: sans-serif;\">").append("<h1><strong>Version: ")
+ .append(Cache.getProperty("VERSION")).append("</strong></h1>").append("<strong>Built: <em>")
+ .append(Cache.getDefault("BUILD_DATE", "unknown")).append("</em> from ")
+ .append(Cache.getBuildDetailsForSplash()).append("</strong>");
String latestVersion = Cache.getDefault("LATEST_VERSION", "Checking");
- if (latestVersion.equals("Checking"))
- {
+ if (latestVersion.equals("Checking")) {
// JBP removed this message for 2.11: May be reinstated in future version
// message.append("<br>...Checking latest version...</br>");
- }
- else if (!latestVersion.equals(Cache.getProperty("VERSION")))
- {
+ } else if (!latestVersion.equals(Cache.getProperty("VERSION"))) {
boolean red = false;
- if (Cache.getProperty("VERSION").toLowerCase()
- .indexOf("automated build") == -1)
- {
+ if (Cache.getProperty("VERSION").toLowerCase(Locale.ROOT).indexOf("automated build") == -1) {
red = true;
// Displayed when code version and jnlp version do not match and code
// version is not a development build
message.append("<div style=\"color: #FF0000;font-style: bold;\">");
}
- message.append("<br>!! Version ")
- .append(Cache.getDefault("LATEST_VERSION", "..Checking.."))
- .append(" is available for download from ")
- .append(Cache.getDefault("www.jalview.org",
- "http://www.jalview.org"))
- .append(" !!");
- if (red)
- {
+ message.append("<br>!! Version ").append(Cache.getDefault("LATEST_VERSION", "..Checking.."))
+ .append(" is available for download from ")
+ .append(Cache.getDefault("www.jalview.org", "https://www.jalview.org")).append(" !!");
+ if (red) {
message.append("</div>");
}
}
message.append(Cache.getDefault("AUTHORFNAMES", DEFAULT_AUTHORS));
message.append(CITATION);
+ message.append("</div>");
+
return message.toString();
}
* Action on requesting Help documentation
*/
@Override
- public void documentationMenuItem_actionPerformed()
- {
- try
- {
- if (Platform.isJS())
- {
- BrowserLauncher.openURL("http://www.jalview.org/help.html");
- }
- else
+ public void documentationMenuItem_actionPerformed() {
+ try {
+ if (Platform.isJS()) {
+ BrowserLauncher.openURL("https://www.jalview.org/help.html");
+ } else
/**
* Java only
*
{
Help.showHelpWindow();
}
- } catch (Exception ex)
- {
+ } catch (Exception ex) {
System.err.println("Error opening help: " + ex.getMessage());
}
}
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.");
}
/*
return;
}
- AlignmentViewport source = null, target = null;
+ AlignViewportI source = null;
+ AlignViewportI target = null;
if (frames[0] instanceof AlignFrame)
{
source = ((AlignFrame) frames[0]).getCurrentView();
* DOCUMENT ME!
*/
@Override
- protected void preferences_actionPerformed(ActionEvent e)
- {
- new Preferences();
+ protected void preferences_actionPerformed(ActionEvent e) {
+ Preferences.openPreferences();
}
/**
}
}
- if (approveSave || autoSave)
- {
+ if (approveSave || autoSave) {
final Desktop me = this;
final java.io.File chosenFile = projectFile;
new Thread(new Runnable()
+ 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(
new OOMWarning("Whilst loading project from " + choice, oom);
} catch (Exception ex)
{
- Cache.log.error(
+ jalview.bin.Console.error(
"Problems whilst loading project from " + choice, ex);
JvOptionPane.showMessageDialog(getDesktopPane(),
MessageManager.formatMessage(
JvOptionPane.WARNING_MESSAGE);
}
}
- }).start();
+ }, "Project Loader").start();
}
});
{
source.showFeatureSettingsUI();
}
+
}
public JInternalFrame[] getAllFrames()
10, getHeight() - fm.getHeight());
}
}
+
+ // output debug scale message. Important for jalview.bin.HiDPISettingTest2
+ Desktop.debugScaleMessage(Desktop.getDesktopPane().getGraphics());
}
}
openGroovyConsole();
} catch (Exception ex)
{
- Cache.log.error("Groovy Shell Creation failed.", ex);
+ jalview.bin.Console.error("Groovy Shell Creation failed.", ex);
JvOptionPane.showInternalMessageDialog(desktopPane,
MessageManager.getString("label.couldnt_create_groovy_shell"),
*/
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,
+ Platform.SHORTCUT_KEY_MASK),
"Quit");
getRootPane().getActionMap().put("Quit", new AbstractAction()
{
progressBars.put(Long.valueOf(id), addProgressPanel(message));
}
}
+
+ @Override
+ public void removeProgressBar(long id)
+ {
+ //TODO
+ throw new UnsupportedOperationException("not implemented");
+ }
/*
* (non-Javadoc)
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)
{
- boolean alive = true;
- Thread t0 = null, t1 = null, t2 = null;
+ jalview.bin.Console.debug("Starting service discovery");
+
+ var tasks = new ArrayList<Future<?>>();
// JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
- if (true)
+
+ System.out.println("loading services");
+
+ /** @j2sIgnore */
{
// todo: changesupport handlers need to be transferred
if (discoverer == null)
}
// JAL-940 - disabled JWS1 service configuration - always start discoverer
// until we phase out completely
- (t0 = new Thread(discoverer)).start();
+ var f = new FutureTask<Void>(discoverer, null);
+ new Thread(f).start();
+ tasks.add(f);
}
if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
- t2 = jalview.ws.jws2.Jws2Discoverer.getInstance()
- .startDiscoverer(changeSupport);
+ tasks.add(jalview.ws.jws2.Jws2Discoverer.getInstance().startDiscoverer());
}
- Thread t3 = null;
+ if (Cache.getDefault("SHOW_SLIVKA_SERVICES", true))
{
- // TODO: do rest service discovery
+ tasks.add(jalview.ws.slivkaws.SlivkaWSDiscoverer.getInstance().startDiscoverer());
}
if (blocking)
{
- while (alive)
- {
+ for (Future<?> task : tasks) {
try
{
- Thread.sleep(15);
+ // block until all discovery tasks are done
+ task.get();
} catch (Exception e)
{
+ e.printStackTrace();
}
- alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
- || (t3 != null && t3.isAlive())
- || (t0 != null && t0.isAlive());
}
}
}
{
if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
{
- final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
- .getErrorMessages();
+ final WSDiscovererI discoverer = jalview.ws.jws2.Jws2Discoverer
+ .getInstance();
+ final String ermsg = discoverer.getErrorMessages();
+ // CONFLICT:ALT:? final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
if (ermsg != null)
{
if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
}
else
{
- Cache.log.error(
+ jalview.bin.Console.error(
"Errors reported by JABA discovery service. Check web services preferences.\n"
+ ermsg);
}
{
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.");
- }
+ // TODO does error send to stderr if no log exists ?
+ jalview.bin.Console.error("Couldn't handle string " + url + " as a URL.");
}
// ignore any exceptions due to dud links.
}
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);
}
}
});
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());
}
};
"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))
{
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;
}
}
} 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 (File file : (List<File>) t
.getTransferData(DataFlavor.javaFileListFlavor))
{
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");
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));
}
{
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);
}
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());
}
}
- if (Cache.log.isDebugEnabled())
+ if (jalview.bin.Console.isDebugEnabled())
{
if (data == null || !added)
{
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")))
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);
}
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));
+ }
+ }
}