*/
package jalview.gui;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-import jalview.bin.Jalview;
-import jalview.gui.ImageExporter.ImageWriterI;
-import jalview.io.BackupFiles;
-import jalview.io.DataSourceType;
-import jalview.io.FileFormat;
-import jalview.io.FileFormatException;
-import jalview.io.FileFormatI;
-import jalview.io.FileFormats;
-import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
-import jalview.io.IdentifyFile;
-import jalview.io.JalviewFileChooser;
-import jalview.io.JalviewFileView;
-import jalview.jbgui.GSplitFrame;
-import jalview.jbgui.GStructureViewer;
-import jalview.project.Jalview2XML;
-import jalview.structure.StructureSelectionManager;
-import jalview.urls.IdOrgSettings;
-import jalview.util.BrowserLauncher;
-import jalview.util.ImageMaker.TYPE;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-import jalview.util.ShortcutKeyMaskExWrapper;
-import jalview.util.UrlConstants;
-import jalview.viewmodel.AlignmentViewport;
-import jalview.ws.params.ParamManager;
-import jalview.ws.utils.UrlDownloadClient;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileWriter;
+
import java.io.IOException;
+import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import javax.swing.JFrame;
+import jalview.api.StructureSelectionManagerProvider;
+
import org.stackoverflowusers.file.WindowsShortcut;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.gui.ImageExporter.ImageWriterI;
+import jalview.io.BackupFiles;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
+import jalview.io.IdentifyFile;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.jbgui.GSplitFrame;
+import jalview.jbgui.GStructureViewer;
+import jalview.project.Jalview2XML;
+import jalview.structure.StructureSelectionManager;
+import jalview.urls.IdOrgSettings;
+import jalview.util.BrowserLauncher;
+import jalview.util.ImageMaker.TYPE;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.util.ShortcutKeyMaskExWrapper;
+import jalview.util.UrlConstants;
+import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.params.ParamManager;
+import jalview.ws.utils.UrlDownloadClient;
+
/**
* Jalview Desktop
*
*/
public class Desktop extends jalview.jbgui.GDesktop
implements DropTargetListener, ClipboardOwner, IProgressIndicator,
- jalview.api.StructureSelectionManagerProvider
+ StructureSelectionManagerProvider, ApplicationSingletonI
{
- private static int DEFAULT_MIN_WIDTH = 300;
+ 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 DEFAULT_AUTHORS = "The Jalview Authors (See AUTHORS file for current list)";
- private static int DEFAULT_MIN_HEIGHT = 250;
+ private final static int DEFAULT_MIN_WIDTH = 300;
- private static int ALIGN_FRAME_DEFAULT_MIN_WIDTH = 600;
+ private final static int DEFAULT_MIN_HEIGHT = 250;
- private static int ALIGN_FRAME_DEFAULT_MIN_HEIGHT = 70;
+ private final static int ALIGN_FRAME_DEFAULT_MIN_WIDTH = 600;
- private static final String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES";
+ private final static int ALIGN_FRAME_DEFAULT_MIN_HEIGHT = 70;
+
+ private final static String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES";
protected static final String CONFIRM_KEYBOARD_QUIT = "CONFIRM_KEYBOARD_QUIT";
- public static HashMap<String, FileWriter> savingFiles = new HashMap<>();
+ public static HashMap<String, FileWriter> savingFiles = new HashMap<String, FileWriter>();
private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
listener);
}
- /** Singleton Desktop instance */
- public static Desktop instance;
-
- public static MyDesktopPane desktop;
-
- public static MyDesktopPane getDesktop()
+ public static StructureSelectionManager getStructureSelectionManager()
{
- // BH 2018 could use currentThread() here as a reference to a
- // Hashtable<Thread, MyDesktopPane> in JavaScript
- return desktop;
+ return StructureSelectionManager
+ .getStructureSelectionManager(getInstance());
}
static int openFrameCount = 0;
static final int yOffset = 30;
- public static jalview.ws.jws1.Discoverer discoverer;
+ // BH was static
+ public jalview.ws.jws1.Discoverer discoverer;
+
+ //BH was static
+ public Object[] jalviewClipboard;
- public static Object[] jalviewClipboard;
+//BH was static
+ public boolean internalCopy = false;
- public static boolean internalCopy = false;
+ private static int fileLoadingCount = 0;
- static int fileLoadingCount = 0;
+ public JInternalFrame conservationSlider;
+
+ public JInternalFrame PIDSlider;
class MyDesktopManager implements DesktopManager
{
} catch (NullPointerException npe)
{
Point p = getMousePosition();
- instance.showPasteMenu(p.x, p.y);
+ showPasteMenu(p.x, p.y);
}
}
public void endDraggingFrame(JComponent f)
{
delegate.endDraggingFrame(f);
- desktop.repaint();
+ desktopPane.repaint();
}
@Override
public void endResizingFrame(JComponent f)
{
delegate.endResizingFrame(f);
- desktop.repaint();
+ desktopPane.repaint();
}
@Override
// All other methods, simply delegate
}
-
/**
- * Creates a new Desktop object.
+ * Private constructor enforces singleton pattern. It is called by reflection
+ * from ApplicationSingletonProvider.getInstance().
*/
- public Desktop()
+ private Desktop()
{
- super();
- /**
- * 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 = this;
-
- doConfigureStructurePrefs();
- setTitle("Jalview " + Cache.getProperty("VERSION"));
- /*
- if (!Platform.isAMac())
- {
- // this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- }
- else
- {
- this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
- }
- */
-
+ Cache.initLogger();
try
{
- APQHandlers.setAPQHandlers(this);
- } catch (Throwable t)
- {
- System.out.println("Error setting APQHandlers: " + t.toString());
- // t.printStackTrace();
- }
-
- addWindowListener(new WindowAdapter()
- {
+ /**
+ * 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.
+ */
- @Override
- public void windowClosing(WindowEvent ev)
+ doConfigureStructurePrefs();
+ setTitle("Jalview " + Cache.getProperty("VERSION"));
+
+ try
{
- quit();
+ if (Platform.getJavaVersion() >= 11)
+ {
+ // BH use reflection so that this code can be in both the Java8 and Java11 versions
+ Class<?> j11APQHandlers = Class.forName("jalview.gui.APQHandlers");
+ Method meth = j11APQHandlers.getMethod("setAPQHandlers", new Class<?>[] {Desktop.class});
+ meth.invoke(j11APQHandlers.newInstance(), this);
+ }
+ } catch (Throwable t)
+ {
+ System.out.println("Desktop Error setting APQHandlers: " + t.toString());
}
- });
- boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE",
- false);
+ addWindowListener(new WindowAdapter()
+ {
+
+ @Override
+ public void windowClosing(WindowEvent ev)
+ {
+ quit();
+ }
+ });
+
+ boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE",
+ false);
boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE",
false);
- desktop = new MyDesktopPane(selmemusage);
+ desktopPane = new MyDesktopPane(selmemusage);
showMemusage.setSelected(selmemusage);
- desktop.setBackground(Color.white);
+ 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);
+ 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())
- {
- getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
- }
+ // BH 2018 - just an experiment to try unclipped JInternalFrames.
+ if (Platform.isJS())
+ {
+ getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
+ }
- getContentPane().add(desktop, BorderLayout.CENTER);
- desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
+ 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
- desktop.setDesktopManager(new MyDesktopManager(
- (Platform.isWindowsAndNotJS() ? new DefaultDesktopManager()
- : Platform.isAMacAndNotJS()
- ? new AquaInternalFrameManager(
- desktop.getDesktopManager())
- : desktop.getDesktopManager())));
+ // 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())));
- 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);
- }
+ 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);
+ }
- if (!Platform.isJS())
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
+ // 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.
- jconsole = new Console(this, showjconsole);
- // add essential build information
- jconsole.setHeader("Jalview Version: "
- + Cache.getProperty("VERSION") + "\n"
- + "Jalview Installation: "
- + Cache.getDefault("INSTALLATION", "unknown")
- + "\n" + "Build Date: "
- + 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"));
+ if (!Platform.isJS() && !Jalview.isSynchronous())
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
- showConsole(showjconsole);
+ jconsole = new Console(this, showjconsole);
+ jconsole.setHeader(Cache.getVersionDetailsForConsole());
+ showConsole(showjconsole);
- showNews.setVisible(false);
+ showNews.setVisible(false);
- experimentalFeatures.setSelected(showExperimental());
+ experimentalFeatures.setSelected(showExperimental());
- getIdentifiersOrgData();
+ getIdentifiersOrgData();
- checkURLLinks();
+ checkURLLinks();
- // Spawn a thread that shows the splashscreen
+ // Spawn a thread that shows the splashscreen
- SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
+ SwingUtilities.invokeLater(new Runnable()
{
- new SplashScreen();
- }
- });
+ @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()
+ {
+ 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);
- }
- });
- }
- this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ Cache.log.debug("Firing service changed event for "
+ + evt.getNewValue());
+ JalviewServicesChanged(evt);
+ }
+
+ });
- this.addWindowListener(new WindowAdapter()
- {
- @Override
- public void windowClosing(WindowEvent evt)
- {
- quit();
}
- });
- MouseAdapter ma;
- this.addMouseListener(ma = new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent evt)
+ if (!Jalview.isSynchronous())
{
- if (evt.isPopupTrigger()) // Mac
+ this.setDropTarget(new java.awt.dnd.DropTarget(desktopPane, this));
+
+ this.addWindowListener(new WindowAdapter()
{
- showPasteMenu(evt.getX(), evt.getY());
- }
- }
+ @Override
+ public void windowClosing(WindowEvent evt)
+ {
+ quit();
+ }
+ });
- @Override
- public void mouseReleased(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Windows
+ MouseAdapter ma;
+ this.addMouseListener(ma = new MouseAdapter()
{
- showPasteMenu(evt.getX(), evt.getY());
- }
- }
- });
- desktop.addMouseListener(ma);
+ @Override
+ public void mousePressed(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Mac
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
+ }
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
+ }
+ });
+ desktopPane.addMouseListener(ma);
+ }
+ } catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
}
/**
showNews(showNews.isSelected());
}
- void showNews(boolean visible)
+ protected void showNews(boolean visible)
{
Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
showNews.setSelected(visible);
public void run()
{
long now = System.currentTimeMillis();
- Desktop.instance.setProgressBar(
+ setProgressBar(
MessageManager.getString("status.refreshing_news"), now);
jvnews.refreshNews();
- Desktop.instance.setProgressBar(null, now);
+ setProgressBar(null, now);
jvnews.showNews();
}
}).start();
return null;
}
- void showPasteMenu(int x, int y)
+ protected void showPasteMenu(int x, int y)
{
JPopupMenu popup = new JPopupMenu();
JMenuItem item = new JMenuItem(
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)
+ // BH fix
+ if (w > 0 && (frame.getWidth() < 1 || frame.getHeight() < 1))
{
frame.setSize(w, h);
}
// A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
// IF JALVIEW IS RUNNING HEADLESS
// ///////////////////////////////////////////////
- if (instance == null || (System.getProperty("java.awt.headless") != null
- && System.getProperty("java.awt.headless").equals("true")))
+ if (Jalview.isHeadlessMode())
{
return;
}
frame.setIconifiable(resizable);
frame.setOpaque(Platform.isJS());
- if (frame.getX() < 1 && frame.getY() < 1)
+ boolean isEmbedded = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
+ if (!isEmbedded && frame.getX() < 1 && frame.getY() < 1)
{
frame.setLocation(xOffset * openFrameCount,
yOffset * ((openFrameCount - 1) % 10) + yOffset);
* 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);
+ JMenuItem menuItem = new JMenuItem(title);
frame.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
public void internalFrameActivated(InternalFrameEvent evt)
{
- JInternalFrame itf = desktop.getSelectedFrame();
+ JInternalFrame itf = getDesktopPane().getSelectedFrame();
if (itf != null)
{
if (itf instanceof AlignFrame)
{
menuItem.removeActionListener(menuItem.getActionListeners()[0]);
}
- windowMenu.remove(menuItem);
+ Desktop.getInstance().windowMenu.remove(menuItem);
}
});
setKeyBindings(frame);
- desktop.add(frame);
+ getDesktopPane().add(frame);
- windowMenu.add(menuItem);
+ Desktop.getInstance().windowMenu.add(menuItem);
frame.toFront();
try
{
if (!internalCopy)
{
- Desktop.jalviewClipboard = null;
+ Desktop.getInstance().jalviewClipboard = null;
}
internalCopy = false;
{
String msg = MessageManager
.formatMessage("label.couldnt_locate", url);
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, msg,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
+ msg,
MessageManager.getString("label.url_not_found"),
JvOptionPane.WARNING_MESSAGE);
};
String dialogOption = MessageManager
.getString("label.input_alignment_from_url");
- JvOptionPane.newOptionDialog(desktop).setResponseHandler(0, action)
+ JvOptionPane.newOptionDialog(getDesktopPane())
+ .setResponseHandler(0, action)
.showInternalDialog(panel, dialogOption,
JvOptionPane.YES_NO_CANCEL_OPTION,
JvOptionPane.PLAIN_MESSAGE, null, options,
@Override
public void aboutMenuItem_actionPerformed(ActionEvent e)
{
- // StringBuffer message = getAboutMessage(false);
- // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- //
- // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
new Thread(new Runnable()
{
@Override
public void run()
{
+ // BH! true meaning "interactive" here (applet branch); was false in develop version??
new SplashScreen(true);
}
}).start();
}
- public StringBuffer getAboutMessage(boolean shortv)
+ /**
+ * Returns the html text for the About screen, including any available version
+ * number, build details, author details and citation reference, but without
+ * the enclosing {@code html} tags
+ *
+ * @return
+ */
+ public String getAboutMessage()
{
- StringBuffer message = new StringBuffer();
- message.append("<html>");
- if (shortv)
- {
- message.append("<h1><strong>Version: "
- + Cache.getProperty("VERSION")
- + "</strong></h1>");
- message.append("<strong>Built: <em>"
- + Cache.getDefault("BUILD_DATE", "unknown") + "</em> from "
- + Cache.getBuildDetailsForSplash()
- + "</strong>");
+ 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>");
- }
- else
- {
-
- message.append("<strong>Version "
- + Cache.getProperty("VERSION")
- + "; last updated: "
- + Cache.getDefault("BUILD_DATE", "unknown"));
- }
-
- if (Cache.getDefault("LATEST_VERSION", "Checking")
- .equals("Checking"))
+ String latestVersion = Cache.getDefault("LATEST_VERSION", "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 (!Cache.getDefault("LATEST_VERSION", "Checking")
- .equals(Cache.getProperty("VERSION")))
+ else if (!latestVersion.equals(Cache.getProperty("VERSION")))
{
boolean red = false;
if (Cache.getProperty("VERSION").toLowerCase()
message.append("<div style=\"color: #FF0000;font-style: bold;\">");
}
- message.append("<br>!! Version "
- + Cache.getDefault("LATEST_VERSION",
- "..Checking..")
- + " is available for download from "
- + Cache.getDefault("www.jalview.org",
- "http://www.jalview.org")
- + " !!");
+ 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("</div>");
}
}
- message.append("<br>Authors: " + Cache.getDefault(
- "AUTHORFNAMES",
- "The Jalview Authors (See AUTHORS file for current list)")
- + "<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"
- + "</html>");
- return message;
+ message.append("<br>Authors: ");
+ message.append(Cache.getDefault("AUTHORFNAMES", DEFAULT_AUTHORS));
+ message.append(CITATION);
+
+ return message.toString();
}
/**
@Override
public void closeAll_actionPerformed(ActionEvent e)
{
+ if (desktopPane == null)
+ {
+ return;
+ }
// TODO show a progress bar while closing?
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
for (int i = 0; i < frames.length; i++)
{
try
* reset state of singleton objects as appropriate (clear down session state
* when all windows are closed)
*/
- StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(this);
- if (ssm != null)
- {
- ssm.resetAll();
- }
+ getStructureSelectionManager().resetAll();
}
@Override
@Override
protected void showMemusage_actionPerformed(ActionEvent e)
{
- desktop.showMemoryUsage(showMemusage.isSelected());
+ getDesktopPane().showMemoryUsage(showMemusage.isSelected());
}
/*
void reorderAssociatedWindows(boolean minimize, boolean close)
{
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = getDesktopPane().getAllFrames();
if (frames == null || frames.length < 1)
{
return;
saveState_actionPerformed(true);
}
- private void setProjectFile(File choice)
+ protected void setProjectFile(File choice)
{
this.projectFile = choice;
}
{
try
{
- new Jalview2XML().loadJalviewAlign(choice);
+ // BH was String "choice" here but needs to be File object
+ new Jalview2XML().loadJalviewAlign(selectedFile);
} catch (OutOfMemoryError oom)
{
new OOMWarning("Whilst loading project from " + choice, oom);
{
Cache.log.error(
"Problems whilst loading project from " + choice, ex);
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.error_whilst_loading_project_from",
new Object[]
{
progressPanel = new JPanel(new GridLayout(1, 1));
totalProgressCount = 0;
- instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
+ getContentPane().add(progressPanel, BorderLayout.SOUTH);
}
JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
JProgressBar progressBar = new JProgressBar();
((GridLayout) progressPanel.getLayout()).setRows(
((GridLayout) progressPanel.getLayout()).getRows() + 1);
++totalProgressCount;
- instance.validate();
+ validate();
return thisprogress;
}
*/
public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
{
- if (Desktop.desktop == null)
+ if (Desktop.getDesktopPane() == null)
{
// no frames created and in headless mode
// TODO: verify that frames are recoverable when in headless mode
public static AlignmentViewport[] getViewports(String sequenceSetId)
{
List<AlignmentViewport> viewp = new ArrayList<>();
- if (desktop != null)
+ if (getDesktopPane() != null)
{
AlignFrame[] frames = Desktop.getAlignFrames();
return;
}
+ // BH! not in applet branch
+ // FIXME: ideally should use UI interface API
+ FeatureSettings viewFeatureSettings = (af.featureSettings != null
+ && af.featureSettings.isOpen())
+ ? af.featureSettings
+ : null;
+ Rectangle fsBounds = af.getFeatureSettingsGeometry();
for (int i = 0; i < size; i++)
{
AlignmentPanel ap = af.alignPanels.get(i);
AlignFrame newaf = new AlignFrame(ap);
+ // BH! not in applet branch
+ // transfer reference for existing feature settings to new alignFrame
+ if (ap == af.alignPanel)
+ {
+ if (viewFeatureSettings != null && viewFeatureSettings.fr.ap == ap)
+ {
+ newaf.featureSettings = viewFeatureSettings;
+ }
+ newaf.setFeatureSettingsGeometry(fsBounds);
+ }
+
/*
* Restore the view's last exploded frame geometry if known. Multiple
* views from one exploded frame share and restore the same (frame)
addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
+ // BH! not in applet branch
+ // 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()
+ && af.alignPanel.getAlignViewport().isShowSequenceFeatures())
+ {
+ newaf.showFeatureSettingsUI();
+ }
}
+ // BH! not in applet branch
+ af.featureSettings = null;
af.alignPanels.clear();
af.closeMenuItem_actionPerformed(true);
{
source.viewport.setGatherViewsHere(true);
source.viewport.setExplodedGeometry(source.getBounds());
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = getAllFrames();
String viewId = source.viewport.getSequenceSetId();
for (int t = 0; t < frames.length; t++)
if (gatherThis)
{
- af.alignPanels.clear();
- af.closeMenuItem_actionPerformed(true);
+ if (af.featureSettings != null && af.featureSettings.isOpen())
+ {
+ if (source.featureSettings == null)
+ {
+ // preserve the feature settings geometry for this frame
+ source.featureSettings = af.featureSettings;
+ source.setFeatureSettingsGeometry(
+ af.getFeatureSettingsGeometry());
+ }
+ else
+ {
+ // close it and forget
+ af.featureSettings.close();
+ }
+ }
+ af.alignPanels.clear();
+ af.closeMenuItem_actionPerformed(true);
+ }
}
}
+ // refresh the feature setting UI for the source frame if it exists
+ if (source.featureSettings != null
+ && source.featureSettings.isOpen())
+ {
+ source.showFeatureSettingsUI();
}
}
public JInternalFrame[] getAllFrames()
{
- return desktop.getAllFrames();
+ return desktopPane.getAllFrames();
}
/**
while (li.hasNext())
{
String link = li.next();
- if (link.contains(jalview.util.UrlConstants.SEQUENCE_ID)
+ if (link.contains(UrlConstants.SEQUENCE_ID)
&& !UrlConstants.isDefaultString(link))
{
check = true;
});
msgPanel.add(jcb);
- JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
+ JvOptionPane.showMessageDialog(desktopPane, msgPanel,
MessageManager
.getString("label.SEQUENCE_ID_no_longer_used"),
JvOptionPane.WARNING_MESSAGE);
{
if (Jalview.isHeadlessMode())
{
- // Desktop.desktop is null in headless mode
- return new AlignFrame[] { Jalview.currentAlignFrame };
+ // Desktop.getDesktopPane() is null in headless mode
+ return new AlignFrame[] { Jalview.getCurrentAlignFrame() };
}
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
if (frames == null)
{
*/
public GStructureViewer[] getJmols()
{
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
if (frames == null)
{
} catch (Exception ex)
{
Cache.log.error("Groovy Shell Creation failed.", ex);
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(desktopPane,
MessageManager.getString("label.couldnt_create_groovy_shell"),
MessageManager.getString("label.groovy_support_failed"),
/**
* Open the Groovy console
*/
- void openGroovyConsole()
+ private void openGroovyConsole()
{
if (groovyConsole == null)
{
{
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()),
+ ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()),
"Quit");
getRootPane().getActionMap().put("Quit", new AbstractAction()
{
@Override
public void setProgressBar(String message, long id)
{
- Platform.timeCheck("Desktop " + message, Platform.TIME_MARK);
+ // Platform.timeCheck("Desktop " + message, Platform.TIME_MARK);
if (progressBars == null)
{
*/
public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
{
- if (desktop != null)
+ if (getDesktopPane() != null)
{
AlignmentPanel[] aps = getAlignmentPanels(
viewport.getSequenceSetId());
return null;
}
- public VamsasApplication getVamsasApplication()
- {
- // TODO: JAL-3311 remove remaining code from Jalview relating to VAMSAS
- return null;
-
- }
-
/**
* flag set if jalview GUI is being operated programmatically
*/
// todo: changesupport handlers need to be transferred
if (discoverer == null)
{
- discoverer = new jalview.ws.jws1.Discoverer();
- // register PCS handler for desktop.
+ discoverer = jalview.ws.jws1.Discoverer.getInstance();
+ // register PCS handler for getDesktopPane().
discoverer.addPropertyChangeListener(changeSupport);
}
// JAL-940 - disabled JWS1 service configuration - always start discoverer
if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
- t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
+ t2 = jalview.ws.jws2.Jws2Discoverer.getInstance()
.startDiscoverer(changeSupport);
}
Thread t3 = null;
{
if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
{
- final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
+ final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
.getErrorMessages();
if (ermsg != null)
{
*
* jd.waitForInput();
*/
- JvOptionPane.showConfirmDialog(Desktop.desktop,
+ JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
new JLabel("<html><table width=\"450\"><tr><td>"
+ ermsg + "</td></tr></table>"
+ "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
}
}
- private Runnable serviceChangedDialog = null;
+ Runnable serviceChangedDialog = null;
/**
* start a thread to open a URL in the configured browser. Pops up a warning
*/
public static void showUrl(final String url)
{
- showUrl(url, Desktop.instance);
+ showUrl(url, Desktop.getInstance());
}
/**
{
try
{
- if (progress != null)
+ if (progress != null && !Platform.isJS())
{
progress.setProgressBar(MessageManager
.formatMessage("status.opening_params", new Object[]
{ url }), this.hashCode());
}
- jalview.util.BrowserLauncher.openURL(url);
+ Platform.openURL(url);
} catch (Exception ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.web_browser_not_found_unix"),
MessageManager.getString("label.web_browser_not_found"),
ex.printStackTrace();
}
- if (progress != null)
+ if (progress != null && !Platform.isJS())
{
progress.setProgressBar(null, this.hashCode());
}
}).start();
}
- public static WsParamSetManager wsparamManager = null;
+ private WsParamSetManager wsparamManager = null;
public static ParamManager getUserParameterStore()
{
- if (wsparamManager == null)
+ Desktop d = Desktop.getInstance();
+ if (d.wsparamManager == null)
{
- wsparamManager = new WsParamSetManager();
+ d.wsparamManager = new WsParamSetManager();
}
- return wsparamManager;
+ return d.wsparamManager;
}
/**
*/
private java.util.concurrent.Semaphore block = new Semaphore(0);
- private static groovy.ui.Console groovyConsole;
+ // BH was static
+ private groovy.ui.Console groovyConsole;
+
+ public StructureViewer lastTargetedView;
/**
* add another dialog thread to the queue
{
}
}
- if (instance == null)
+ // BH! Q: do we mean System.headless ? or "nogui/nodisplay" headless?
+ if (Jalview.isHeadlessMode())
{
return;
}
String topViewId = myTopFrame.viewport.getSequenceSetId();
String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
for (JInternalFrame frame : frames)
{
if (frame instanceof SplitFrame && frame != source)
public static groovy.ui.Console getGroovyConsole()
{
- return groovyConsole;
+ Desktop desktop = Desktop.getInstance();
+ return desktop == null ? null : desktop.groovyConsole;
}
/**
* - the payload from the drop event
* @throws Exception
*/
+ @SuppressWarnings("unchecked")
public static void transferFromDropTarget(List<Object> files,
List<DataSourceType> protocols, DropTargetDropEvent evt,
Transferable t) throws Exception
{
// Works on Windows and MacOSX
Cache.log.debug("Drop handled as javaFileListFlavor");
- for (Object file : (List) t
+ for (Object file : (List<Object>) t
.getTransferData(DataFlavor.javaFileListFlavor))
{
files.add(file);
Class<? extends StructureViewerBase> structureViewerClass)
{
List<StructureViewerBase> result = new ArrayList<>();
- JInternalFrame[] frames = Desktop.instance.getAllFrames();
+ JInternalFrame[] frames = getAllFrames();
for (JInternalFrame frame : frames)
{
}
return result;
}
+
+
+
+ public MyDesktopPane desktopPane;
+
+ /**
+ * Get the instance of the JDesktopPane from the application-local Desktop
+ * (JFrame) instance
+ *
+ * The key here is that the Java application can have multiple static
+ * instances of the desktop JFrame because those instances are sandboxed, but
+ * the SwingJS JFrames will be in the same VM-like space. So we need
+ * application singletons, at least for JavaScript.
+ *
+ * @return
+ */
+ public static MyDesktopPane getDesktopPane()
+ {
+ Desktop desktop = Desktop.getInstance();
+ return desktop == null ? null : desktop.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);
+ }
+
}