*/
package jalview.gui;
-import java.util.Locale;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.Hashtable;
import java.util.List;
import java.util.ListIterator;
+import java.util.Locale;
import java.util.Vector;
+import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.event.InternalFrameAdapter;
import jalview.io.JalviewFileView;
import jalview.jbgui.GSplitFrame;
import jalview.jbgui.GStructureViewer;
+import jalview.jbgui.QuitHandler;
+import jalview.jbgui.QuitHandler.QResponse;
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;
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>();
*/
if (Platform.isLinux())
{
+ 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();
}
}
- /**
- * 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());
+ // override quit handling when GUI OS close [X] button pressed
+ this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter()
{
-
@Override
public void windowClosing(WindowEvent ev)
{
- quit();
+ QuitHandler.QResponse ret = desktopQuit(true, true); // ui, disposeFlag
}
});
this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
- this.addWindowListener(new WindowAdapter()
- {
- @Override
- public void windowClosing(WindowEvent evt)
- {
- quit();
- }
- });
-
MouseAdapter ma;
this.addMouseListener(ma = new MouseAdapter()
{
MessageManager.getString("label.open_local_file"));
chooser.setToolTipText(MessageManager.getString("action.open"));
- chooser.setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
- {
- File selectedFile = chooser.getSelectedFile();
- Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
+ chooser.setResponseHandler(0, () -> {
+ File selectedFile = chooser.getSelectedFile();
+ Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
- FileFormatI format = chooser.getSelectedFormat();
+ FileFormatI format = chooser.getSelectedFormat();
- /*
- * 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.
- */
- if (FileFormats.getInstance().isIdentifiable(format))
+ /*
+ * 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.
+ */
+ if (FileFormats.getInstance().isIdentifiable(format))
+ {
+ try
{
- try
- {
- format = new IdentifyFile().identify(selectedFile,
- DataSourceType.FILE);
- } catch (FileFormatException e)
- {
- // format = null; //??
- }
+ format = new IdentifyFile().identify(selectedFile,
+ DataSourceType.FILE);
+ } catch (FileFormatException e)
+ {
+ // format = null; //??
}
-
- new FileLoader().LoadFile(viewport, selectedFile,
- DataSourceType.FILE, format);
}
+
+ new FileLoader().LoadFile(viewport, selectedFile, DataSourceType.FILE,
+ format);
+ return null;
});
chooser.showOpenDialog(this);
}
Object[] options = new Object[] { MessageManager.getString("action.ok"),
MessageManager.getString("action.cancel") };
- Runnable action = new Runnable()
- {
- @Override
- public void run()
- {
- @SuppressWarnings("unchecked")
- String url = (history instanceof JTextField
- ? ((JTextField) history).getText()
- : ((JComboBox<String>) history).getEditor().getItem()
- .toString().trim());
+ Callable<Void> action = () -> {
+ @SuppressWarnings("unchecked")
+ String url = (history instanceof JTextField
+ ? ((JTextField) history).getText()
+ : ((JComboBox<String>) history).getEditor().getItem()
+ .toString().trim());
- if (url.toLowerCase(Locale.ROOT).endsWith(".jar"))
+ if (url.toLowerCase(Locale.ROOT).endsWith(".jar"))
+ {
+ if (viewport != null)
{
- if (viewport != null)
- {
- new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
- FileFormat.Jalview);
- }
- else
- {
- new FileLoader().LoadFile(url, DataSourceType.URL,
- FileFormat.Jalview);
- }
+ new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
+ FileFormat.Jalview);
}
else
{
- FileFormatI format = null;
- try
- {
- format = new IdentifyFile().identify(url, DataSourceType.URL);
- } catch (FileFormatException e)
- {
- // TODO revise error handling, distinguish between
- // URL not found and response not valid
- }
+ new FileLoader().LoadFile(url, DataSourceType.URL,
+ FileFormat.Jalview);
+ }
+ }
+ else
+ {
+ FileFormatI format = null;
+ try
+ {
+ format = new IdentifyFile().identify(url, DataSourceType.URL);
+ } catch (FileFormatException e)
+ {
+ // TODO revise error handling, distinguish between
+ // URL not found and response not valid
+ }
- if (format == null)
- {
- String msg = MessageManager
- .formatMessage("label.couldnt_locate", url);
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, msg,
- MessageManager.getString("label.url_not_found"),
- JvOptionPane.WARNING_MESSAGE);
+ if (format == null)
+ {
+ String msg = MessageManager.formatMessage("label.couldnt_locate",
+ url);
+ JvOptionPane.showInternalMessageDialog(Desktop.desktop, msg,
+ MessageManager.getString("label.url_not_found"),
+ JvOptionPane.WARNING_MESSAGE);
- return;
- }
+ return null; // Void
+ }
- if (viewport != null)
- {
- new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
- format);
- }
- else
- {
- new FileLoader().LoadFile(url, DataSourceType.URL, format);
- }
+ if (viewport != null)
+ {
+ new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
+ format);
+ }
+ else
+ {
+ new FileLoader().LoadFile(url, DataSourceType.URL, format);
}
}
+ return null; // Void
};
String dialogOption = MessageManager
.getString("label.input_alignment_from_url");
}
/*
- * Exit the program
+ * Check with user and saving files before actually quitting
*/
- @Override
- public void quit()
+ public void desktopQuit()
{
- Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
- Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
- storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
- getWidth(), getHeight()));
+ desktopQuit(true, false);
+ }
- if (jconsole != null)
- {
- storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
- jconsole.stopConsole();
- }
- if (jvnews != null)
- {
- storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
+ public QuitHandler.QResponse desktopQuit(boolean ui, boolean disposeFlag)
+ {
+ final Callable<QuitHandler.QResponse> doDesktopQuit = () -> {
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
+ Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
+ storeLastKnownDimensions("", new Rectangle(getBounds().x,
+ getBounds().y, getWidth(), getHeight()));
- }
- if (dialogExecutor != null)
- {
- dialogExecutor.shutdownNow();
- }
- closeAll_actionPerformed(null);
+ if (jconsole != null)
+ {
+ storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
+ jconsole.stopConsole();
+ }
- if (groovyConsole != null)
- {
- // suppress a possible repeat prompt to save script
- groovyConsole.setDirty(false);
- groovyConsole.exit();
- }
+ if (jvnews != null)
+ {
+ storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
+
+ }
+
+ if (dialogExecutor != null)
+ {
+ dialogExecutor.shutdownNow();
+ }
+
+ closeAll_actionPerformed(null);
+
+ if (groovyConsole != null)
+ {
+ // suppress a possible repeat prompt to save script
+ groovyConsole.setDirty(false);
+ groovyConsole.exit();
+ }
+
+ if (QuitHandler.gotQuitResponse() == QResponse.FORCE_QUIT)
+ {
+ // note that shutdown hook will not be run
+ jalview.bin.Console.debug("Force Quit selected by user");
+ Runtime.getRuntime().halt(0);
+ }
+
+ jalview.bin.Console.debug("Quit selected by user");
+ if (disposeFlag)
+ {
+ instance.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ // instance.dispose();
+ }
+ jalview.bin.Console.debug("**** BEFORE quit");
+ jalview.bin.Console.debug("**** QuitHandler.gotQuitResponse="
+ + QuitHandler.gotQuitResponse());
+ instance.quit();
+ jalview.bin.Console.debug("**** AFTER quit");
+
+ return QuitHandler.gotQuitResponse();
+ };
+
+ return QuitHandler.getQuitResponse(ui, doDesktopQuit, doDesktopQuit,
+ QuitHandler.defaultCancelQuit);
+ }
+
+ /**
+ * Don't call this directly, use desktopQuit() above. Exits the program.
+ */
+ @Override
+ public void quit()
+ {
+ // this will run the shutdownHook but QuitHandler.getQuitResponse() should
+ // not run a second time if gotQuitResponse flag has been set (i.e. user
+ // confirmed quit of some kind).
System.exit(0);
}
// allowBackupFiles
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
- chooser.setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
+ chooser.setResponseHandler(0, () -> {
+ File selectedFile = chooser.getSelectedFile();
+ setProjectFile(selectedFile);
+ String choice = selectedFile.getAbsolutePath();
+ Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
+ new Thread(new Runnable()
{
- File selectedFile = chooser.getSelectedFile();
- setProjectFile(selectedFile);
- String choice = selectedFile.getAbsolutePath();
- Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
- new Thread(new Runnable()
+ @Override
+ public void run()
{
- @Override
- public void run()
+ try
{
- try
- {
- new Jalview2XML().loadJalviewAlign(selectedFile);
- } catch (OutOfMemoryError oom)
- {
- 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);
- }
+ new Jalview2XML().loadJalviewAlign(selectedFile);
+ } catch (OutOfMemoryError oom)
+ {
+ 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);
}
- }, "Project Loader").start();
- }
+ }
+ }, "Project Loader").start();
+ return null;
});
chooser.showOpenDialog(this);
@Override
public void actionPerformed(ActionEvent e)
{
- quit();
+ desktopQuit();
}
});
}