import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.PromptUserConfig;
+import jalview.gui.QuitHandler;
+import jalview.gui.QuitHandler.QResponse;
import jalview.io.AppletFormatAdapter;
import jalview.io.BioJsHTMLOutput;
import jalview.io.DataSourceType;
if (!Platform.isJS())
{
System.setSecurityManager(null);
+
+ Runtime.getRuntime().addShutdownHook(new Thread()
+ {
+ public void run()
+ {
+ Console.debug("Running shutdown hook");
+ if (QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT)
+ {
+ // Got to here by a SIGTERM signal.
+ // Note we will not actually cancel the quit from here -- it's too
+ // late -- but we can wait for saving files.
+ Console.debug("Checking for saving files");
+ QuitHandler.getQuitResponse(false);
+ }
+ else
+ {
+ Console.debug("Nothing more to do");
+ }
+ Console.debug("Exiting, bye!");
+ // shutdownHook cannot be cancelled, JVM will now halt
+ }
+ });
}
System.out
System.out.println(System.getProperty("os.arch") + " "
+ System.getProperty("os.name") + " "
+ System.getProperty("os.version"));
+
String val = System.getProperty("sys.install4jVersion");
if (val != null)
{
Cache.loadBuildProperties(true);
ArgsParser aparser = new ArgsParser(args);
+
boolean headless = false;
String usrPropsFile = aparser.getValue("props");
- Cache.loadProperties(usrPropsFile); // must do this before
+ Cache.loadProperties(usrPropsFile); // must do this
+ // before
if (usrPropsFile != null)
{
System.out.println(
try
{
Console.initLogger();
- } catch (NoClassDefFoundError error)
+ } catch (
+
+ NoClassDefFoundError error)
{
error.printStackTrace();
System.out.println("\nEssential logging libraries not found."
}
String file = null, data = null;
+
FileFormatI format = null;
+
DataSourceType protocol = null;
+
FileLoader fileLoader = new FileLoader(!headless);
String groovyscript = null; // script to execute after all loading is
System.out.println("No files to open!");
System.exit(1);
}
+
long progress = -1;
// Finally, deal with the remaining input data.
if (file != null)
}
}
}
+
AlignFrame startUpAlframe = null;
// We'll only open the default file if the desktop is visible.
// And the user
UIManager.put("TabbedPane.tabWidthMode", "compact");
UIManager.put("TabbedPane.selectedBackground", Color.white);
}
+
+ Desktop.setLiveDragMode(Cache.getDefault("FLAT_LIVE_DRAG_MODE", true));
return set;
}
}
/**
- * Quit method delegates to Desktop.quit - unless running in headless mode
- * when it just ends the JVM
+ * jalview.bin.Jalview.quit() will just run the non-GUI shutdownHook and exit
*/
public void quit()
{
- if (desktop != null)
- {
- desktop.quit();
- }
- else
- {
- System.exit(0);
- }
+ // System.exit will run the shutdownHook first
+ System.exit(0);
}
public static AlignFrame getCurrentAlignFrame()
import java.util.List;
import java.util.Locale;
import java.util.Vector;
+import java.util.concurrent.Callable;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
*/
void init()
{
+ setFrameIcon(WindowIcons.alignmentIcon);
+
// setBackground(Color.white); // BH 2019
if (!Jalview.isHeadlessMode())
lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
shortName);
+ Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
+ if (lastSaveSuccessful)
+ {
+ this.getViewport().setSavedUpToDate(true);
+ }
+
statusBar.setText(MessageManager.formatMessage(
"label.successfully_saved_to_file_in_format", new Object[]
{ file, format }));
}
AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
- Runnable cancelAction = new Runnable()
- {
- @Override
- public void run()
+ Callable<Void> cancelAction = () -> {
+ lastSaveSuccessful = false;
+ return null;
+ };
+ Callable<Void> outputAction = () -> {
+ // todo defer this to inside formatSequences (or later)
+ AlignmentExportData exportData = viewport.getAlignExportData(options);
+ String output = new FormatAdapter(alignPanel, options)
+ .formatSequences(format, exportData.getAlignment(),
+ exportData.getOmitHidden(),
+ exportData.getStartEndPostions(),
+ viewport.getAlignment().getHiddenColumns());
+ if (output == null)
{
lastSaveSuccessful = false;
}
- };
- Runnable outputAction = new Runnable()
- {
- @Override
- public void run()
+ else
{
- // todo defer this to inside formatSequences (or later)
- AlignmentExportData exportData = viewport
- .getAlignExportData(options);
- String output = new FormatAdapter(alignPanel, options)
- .formatSequences(format, exportData.getAlignment(),
- exportData.getOmitHidden(),
- exportData.getStartEndPostions(),
- viewport.getAlignment().getHiddenColumns());
- if (output == null)
+ // create backupfiles object and get new temp filename destination
+ boolean doBackup = BackupFiles.getEnabled();
+ BackupFiles backupfiles = null;
+ if (doBackup)
{
- lastSaveSuccessful = false;
+ Console.trace("ALIGNFRAME making backupfiles object for " + file);
+ backupfiles = new BackupFiles(file);
}
- else
+ try
{
- // create backupfiles object and get new temp filename destination
- boolean doBackup = BackupFiles.getEnabled();
- BackupFiles backupfiles = null;
- if (doBackup)
+ String tempFilePath = doBackup ? backupfiles.getTempFilePath()
+ : file;
+ Console.trace("ALIGNFRAME setting PrintWriter");
+ PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
+
+ if (backupfiles != null)
{
- Console.trace(
- "ALIGNFRAME making backupfiles object for " + file);
- backupfiles = new BackupFiles(file);
+ Console.trace("ALIGNFRAME about to write to temp file "
+ + backupfiles.getTempFilePath());
}
- try
- {
- String tempFilePath = doBackup ? backupfiles.getTempFilePath()
- : file;
- Console.trace("ALIGNFRAME setting PrintWriter");
- PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
- if (backupfiles != null)
- {
- Console.trace("ALIGNFRAME about to write to temp file "
- + backupfiles.getTempFilePath());
- }
+ out.print(output);
+ Console.trace("ALIGNFRAME about to close file");
+ out.close();
+ Console.trace("ALIGNFRAME closed file");
+ AlignFrame.this.setTitle(file);
+ statusBar.setText(MessageManager.formatMessage(
+ "label.successfully_saved_to_file_in_format", new Object[]
+ { fileName, format.getName() }));
+ lastSaveSuccessful = true;
+ } catch (IOException e)
+ {
+ lastSaveSuccessful = false;
+ Console.error(
+ "ALIGNFRAME Something happened writing the temp file");
+ Console.error(e.getMessage());
+ Console.debug(Cache.getStackTraceString(e));
+ } catch (Exception ex)
+ {
+ lastSaveSuccessful = false;
+ Console.error(
+ "ALIGNFRAME Something unexpected happened writing the temp file");
+ Console.error(ex.getMessage());
+ Console.debug(Cache.getStackTraceString(ex));
+ }
- out.print(output);
- Console.trace("ALIGNFRAME about to close file");
- out.close();
- Console.trace("ALIGNFRAME closed file");
- AlignFrame.this.setTitle(file);
- statusBar.setText(MessageManager.formatMessage(
- "label.successfully_saved_to_file_in_format",
- new Object[]
- { fileName, format.getName() }));
- lastSaveSuccessful = true;
- } catch (IOException e)
- {
- lastSaveSuccessful = false;
- Console.error(
- "ALIGNFRAME Something happened writing the temp file");
- Console.error(e.getMessage());
- Console.debug(Cache.getStackTraceString(e));
- } catch (Exception ex)
- {
- lastSaveSuccessful = false;
- Console.error(
- "ALIGNFRAME Something unexpected happened writing the temp file");
- Console.error(ex.getMessage());
- Console.debug(Cache.getStackTraceString(ex));
- }
+ if (doBackup)
+ {
+ backupfiles.setWriteSuccess(lastSaveSuccessful);
+ Console.debug("ALIGNFRAME writing temp file was "
+ + (lastSaveSuccessful ? "" : "NOT ") + "successful");
+ // do the backup file roll and rename the temp file to actual file
+ Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
+ lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
+ Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
+ + (lastSaveSuccessful ? "" : "un") + "successfully");
+ }
- if (doBackup)
- {
- backupfiles.setWriteSuccess(lastSaveSuccessful);
- Console.debug("ALIGNFRAME writing temp file was "
- + (lastSaveSuccessful ? "" : "NOT ") + "successful");
- // do the backup file roll and rename the temp file to actual file
- Console.trace(
- "ALIGNFRAME about to rollBackupsAndRenameTempFile");
- lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
- Console.debug(
- "ALIGNFRAME performed rollBackupsAndRenameTempFile "
- + (lastSaveSuccessful ? "" : "un")
- + "successfully");
- }
+ Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
+ if (lastSaveSuccessful)
+ {
+ AlignFrame.this.getViewport().setSavedUpToDate(true);
}
}
+ return null;
};
/*
}
else
{
- outputAction.run();
+ try
+ {
+ outputAction.call();
+ } catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
}
FileFormatI fileFormat = FileFormats.getInstance()
.forName(fileFormatName);
AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
- Runnable outputAction = new Runnable()
- {
- @Override
- public void run()
+ Callable<Void> outputAction = () -> {
+ // todo defer this to inside formatSequences (or later)
+ AlignmentExportData exportData = viewport.getAlignExportData(options);
+ CutAndPasteTransfer cap = new CutAndPasteTransfer();
+ cap.setForInput(null);
+ try
{
- // todo defer this to inside formatSequences (or later)
- AlignmentExportData exportData = viewport
- .getAlignExportData(options);
- CutAndPasteTransfer cap = new CutAndPasteTransfer();
- cap.setForInput(null);
- try
- {
- FileFormatI format = fileFormat;
- cap.setText(new FormatAdapter(alignPanel, options)
- .formatSequences(format, exportData.getAlignment(),
- exportData.getOmitHidden(),
- exportData.getStartEndPostions(),
- viewport.getAlignment().getHiddenColumns()));
- Desktop.addInternalFrame(cap, MessageManager.formatMessage(
- "label.alignment_output_command", new Object[]
- { fileFormat.getName() }), 600, 500);
- } catch (OutOfMemoryError oom)
- {
- new OOMWarning("Outputting alignment as " + fileFormat.getName(),
- oom);
- cap.dispose();
- }
+ FileFormatI format = fileFormat;
+ cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
+ format, exportData.getAlignment(),
+ exportData.getOmitHidden(),
+ exportData.getStartEndPostions(),
+ viewport.getAlignment().getHiddenColumns()));
+ Desktop.addInternalFrame(cap, MessageManager.formatMessage(
+ "label.alignment_output_command", new Object[]
+ { fileFormat.getName() }), 600, 500);
+ } catch (OutOfMemoryError oom)
+ {
+ new OOMWarning("Outputting alignment as " + fileFormat.getName(),
+ oom);
+ cap.dispose();
}
+ return null;
};
/*
}
else
{
- outputAction.run();
+ try
+ {
+ outputAction.call();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
}
}
.getString("label.load_jalview_annotations");
chooser.setDialogTitle(tooltip);
chooser.setToolTipText(tooltip);
- chooser.setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
- {
- String choice = chooser.getSelectedFile().getPath();
- Cache.setProperty("LAST_DIRECTORY", choice);
- loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
- }
+ chooser.setResponseHandler(0, () -> {
+ String choice = chooser.getSelectedFile().getPath();
+ Cache.setProperty("LAST_DIRECTORY", choice);
+ loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
+ return null;
});
chooser.showOpenDialog(this);
return;
}
- Runnable okAction = new Runnable()
- {
- @Override
- public void run()
- {
- SequenceI[] cut = sg.getSequences()
- .toArray(new SequenceI[sg.getSize()]);
+ Callable okAction = () -> {
+ SequenceI[] cut = sg.getSequences()
+ .toArray(new SequenceI[sg.getSize()]);
- addHistoryItem(new EditCommand(
- MessageManager.getString("label.cut_sequences"), Action.CUT,
- cut, sg.getStartRes(),
- sg.getEndRes() - sg.getStartRes() + 1,
- viewport.getAlignment()));
+ addHistoryItem(new EditCommand(
+ MessageManager.getString("label.cut_sequences"), Action.CUT,
+ cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
+ viewport.getAlignment()));
- viewport.setSelectionGroup(null);
- viewport.sendSelection();
- viewport.getAlignment().deleteGroup(sg);
+ viewport.setSelectionGroup(null);
+ viewport.sendSelection();
+ viewport.getAlignment().deleteGroup(sg);
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
- if (viewport.getAlignment().getHeight() < 1)
+ viewport.firePropertyChange("alignment", null,
+ viewport.getAlignment().getSequences());
+ if (viewport.getAlignment().getHeight() < 1)
+ {
+ try
+ {
+ AlignFrame.this.setClosed(true);
+ } catch (Exception ex)
{
- try
- {
- AlignFrame.this.setClosed(true);
- } catch (Exception ex)
- {
- }
}
}
+ return null;
};
/*
}
else
{
- okAction.run();
+ try
+ {
+ okAction.call();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
}
}
.formatMessage("label.overview_params", new Object[]
{ this.getTitle() }), true, frame.getWidth(), frame.getHeight(),
true, true);
+ frame.setFrameIcon(WindowIcons.overviewIcon);
frame.pack();
frame.setLayer(JLayeredPane.PALETTE_LAYER);
frame.addInternalFrameListener(
chooser.setToolTipText(
MessageManager.getString("label.load_tree_file"));
- chooser.setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
+ chooser.setResponseHandler(0, () -> {
+ String filePath = chooser.getSelectedFile().getPath();
+ Cache.setProperty("LAST_DIRECTORY", filePath);
+ NewickFile fin = null;
+ try
{
- String filePath = chooser.getSelectedFile().getPath();
- Cache.setProperty("LAST_DIRECTORY", filePath);
- NewickFile fin = null;
- try
- {
- fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
- DataSourceType.FILE));
- viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
- } catch (Exception ex)
- {
- JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
- MessageManager
- .getString("label.problem_reading_tree_file"),
- JvOptionPane.WARNING_MESSAGE);
- ex.printStackTrace();
- }
- if (fin != null && fin.hasWarningMessage())
- {
- JvOptionPane.showMessageDialog(Desktop.desktop,
- fin.getWarningMessage(),
- MessageManager.getString(
- "label.possible_problem_with_tree_file"),
- JvOptionPane.WARNING_MESSAGE);
- }
+ fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
+ DataSourceType.FILE));
+ viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
+ } catch (Exception ex)
+ {
+ JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
+ MessageManager.getString("label.problem_reading_tree_file"),
+ JvOptionPane.WARNING_MESSAGE);
+ ex.printStackTrace();
}
+ if (fin != null && fin.hasWarningMessage())
+ {
+ JvOptionPane.showMessageDialog(Desktop.desktop,
+ fin.getWarningMessage(),
+ MessageManager
+ .getString("label.possible_problem_with_tree_file"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
+ return null;
});
chooser.showOpenDialog(this);
}
chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
final AlignFrame us = this;
- chooser.setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
- {
- String choice = chooser.getSelectedFile().getPath();
- Cache.setProperty("LAST_DIRECTORY", choice);
- SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
- new VCFLoader(choice).loadVCF(seqs, us);
- }
+ chooser.setResponseHandler(0, () -> {
+ String choice = chooser.getSelectedFile().getPath();
+ Cache.setProperty("LAST_DIRECTORY", choice);
+ SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
+ new VCFLoader(choice).loadVCF(seqs, us);
+ return null;
});
chooser.showOpenDialog(null);
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.bin.Cache;
import jalview.bin.Jalview;
import jalview.gui.ImageExporter.ImageWriterI;
+import jalview.gui.QuitHandler.QResponse;
import jalview.io.BackupFiles;
import jalview.io.DataSourceType;
import jalview.io.FileFormat;
public static HashMap<String, FileWriter> savingFiles = new HashMap<String, FileWriter>();
+ private static int DRAG_MODE = JDesktopPane.OUTLINE_DRAG_MODE;
+
+ public static void setLiveDragMode(boolean b)
+ {
+ DRAG_MODE = b ? JDesktopPane.LIVE_DRAG_MODE
+ : JDesktopPane.OUTLINE_DRAG_MODE;
+ }
+
private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
public static boolean nosplash = false;
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
}
});
}
getContentPane().add(desktop, BorderLayout.CENTER);
- desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
+ desktop.setDragMode(DRAG_MODE);
// This line prevents Windows Look&Feel resizing all new windows to maximum
// if previous window was maximised
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()
+ 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"))
{
- @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 (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<Void> 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();
+ }
+ instance.quit();
+
+ return null; // Void
+ };
+
+ 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();
}
});
}
{
frame = new JInternalFrame();
frame.setContentPane(this);
+ frame.setFrameIcon(WindowIcons.featuresIcon);
Rectangle bounds = af.getFeatureSettingsGeometry();
String title;
if (af.getAlignPanels().size() > 1 || Desktop.getAlignmentPanels(
chooser.setDialogTitle(
MessageManager.getString("label.load_feature_colours"));
chooser.setToolTipText(MessageManager.getString("action.load"));
- chooser.setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
- {
- File file = chooser.getSelectedFile();
- load(file);
- }
+ chooser.setResponseHandler(0, () -> {
+ File file = chooser.getSelectedFile();
+ load(file);
+ return null;
});
chooser.showOpenDialog(this);
}
package jalview.gui;
+ import java.awt.AWTEvent;
+ import java.awt.ActiveEvent;
import java.awt.Component;
+ import java.awt.Container;
import java.awt.Dialog.ModalityType;
+ import java.awt.EventQueue;
import java.awt.HeadlessException;
+ import java.awt.MenuComponent;
+ import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+ import java.awt.event.MouseAdapter;
+ import java.awt.event.MouseMotionAdapter;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
+import javax.swing.JFrame;
import javax.swing.JInternalFrame;
+ import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager;
+ import javax.swing.event.InternalFrameEvent;
+ import javax.swing.event.InternalFrameListener;
import jalview.util.Platform;
import jalview.util.dialogrunner.DialogRunnerI;
{
private static final long serialVersionUID = -3019167117756785229L;
- private static Object mockResponse = JOptionPane.CANCEL_OPTION;
+ private static Object mockResponse = JvOptionPane.CANCEL_OPTION;
private static boolean interactiveMode = true;
private Component parentComponent;
- private Map<Object, Runnable> callbacks = new HashMap<>();
+ private Map<Object, Callable<Void>> callbacks = new HashMap<>();
/*
* JalviewJS reports user choice in the dialog as the selected
public JvOptionPane(final Component parent)
{
this.parentComponent = Platform.isJS() ? this : parent;
- this.setIcon(WindowIcons.logoIcon);
}
public static int showConfirmDialog(Component parentComponent,
}
switch (optionType)
{
- case JOptionPane.YES_NO_CANCEL_OPTION:
+ case JvOptionPane.YES_NO_CANCEL_OPTION:
// FeatureRenderer amendFeatures ?? TODO ??
// Chimera close
// PromptUserConfig
// $FALL-THROUGH$
default:
- case JOptionPane.YES_NO_OPTION:
+ case JvOptionPane.YES_NO_OPTION:
// PromptUserConfig usage stats
// for now treated as "OK CANCEL"
// $FALL-THROUGH$
- case JOptionPane.OK_CANCEL_OPTION:
+ case JvOptionPane.OK_CANCEL_OPTION:
// will fall back to simple HTML
return JOptionPane.showConfirmDialog(parentComponent, message, title,
optionType);
}
switch (optionType)
{
- case JOptionPane.YES_NO_CANCEL_OPTION:
+ case JvOptionPane.YES_NO_CANCEL_OPTION:
// ColourMenuHelper.addMenuItmers.offerRemoval TODO
- case JOptionPane.YES_NO_OPTION:
+ case JvOptionPane.YES_NO_OPTION:
// UserDefinedColoursSave -- relevant? TODO
// $FALL-THROUGH$
default:
- case JOptionPane.OK_CANCEL_OPTION:
+ case JvOptionPane.OK_CANCEL_OPTION:
// EditNameDialog --- uses panel for messsage TODO
}
switch (optionType)
{
- case JOptionPane.YES_NO_CANCEL_OPTION:
- case JOptionPane.YES_NO_OPTION:
+ case JvOptionPane.YES_NO_CANCEL_OPTION:
+ case JvOptionPane.YES_NO_OPTION:
// UserQuestionanaireCheck
// VamsasApplication
// $FALL-THROUGH$
default:
- case JOptionPane.OK_CANCEL_OPTION:
+ case JvOptionPane.OK_CANCEL_OPTION:
// will fall back to simple HTML
return JOptionPane.showConfirmDialog(parentComponent, message, title,
optionType, messageType);
}
switch (optionType)
{
- case JOptionPane.YES_NO_CANCEL_OPTION:
- case JOptionPane.YES_NO_OPTION:
+ case JvOptionPane.YES_NO_CANCEL_OPTION:
+ case JvOptionPane.YES_NO_OPTION:
//$FALL-THROUGH$
default:
- case JOptionPane.OK_CANCEL_OPTION:
+ case JvOptionPane.OK_CANCEL_OPTION:
// Preferences editLink/newLink
return JOptionPane.showConfirmDialog(parentComponent, message, title,
optionType, messageType, icon);
public static void resetMock()
{
- setMockResponse(JOptionPane.CANCEL_OPTION);
+ setMockResponse(JvOptionPane.CANCEL_OPTION);
setInteractiveMode(true);
}
{
switch (messageType)
{
- case JOptionPane.WARNING_MESSAGE:
+ case JvOptionPane.WARNING_MESSAGE:
prefix = "WARNING! ";
break;
- case JOptionPane.ERROR_MESSAGE:
+ case JvOptionPane.ERROR_MESSAGE:
prefix = "ERROR! ";
break;
default:
* @param string2
* @return
*/
+ public static JvOptionPane newOptionDialog()
+ {
+ return new JvOptionPane(null);
+ }
+
public static JvOptionPane newOptionDialog(Component parentComponent)
{
return new JvOptionPane(parentComponent);
initialValue, true);
}
- public void showDialog(String message, String title, int optionType,
+ public void showDialog(Object message, String title, int optionType,
int messageType, Icon icon, Object[] options, Object initialValue,
boolean modal)
{
+ showDialog(message, title, optionType, messageType, icon, options,
+ initialValue, modal, null);
+ }
+
+ public void showDialog(Object message, String title, int optionType,
+ int messageType, Icon icon, Object[] options, Object initialValue,
+ boolean modal, JButton[] buttons)
+ {
if (!isInteractiveMode())
{
handleResponse(getMockResponse());
if (modal)
{
+ boolean useButtons = false;
+ Object initialValueButton = null;
+ NOTNULL: if (buttons != null)
+ {
+ if (buttons.length != options.length)
+ {
+ jalview.bin.Console.error(
+ "Supplied buttons array not the same length as supplied options array.");
+ break NOTNULL;
+ }
+ int[] buttonActions = { JOptionPane.YES_OPTION,
+ JOptionPane.NO_OPTION, JOptionPane.CANCEL_OPTION };
+ for (int i = 0; i < options.length; i++)
+ {
+ Object o = options[i];
+ jalview.bin.Console.debug(
+ "Setting button " + i + " to '" + o.toString() + "'");
+ JButton jb = buttons[i];
+
+ if (o.equals(initialValue))
+ initialValueButton = jb;
+
+ int buttonAction = buttonActions[i];
+ Callable<Void> action = callbacks.get(buttonAction);
+ jb.setText((String) o);
+ jb.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+
+ Object obj = e.getSource();
+ if (obj == null || !(obj instanceof Component))
+ {
+ jalview.bin.Console.debug(
+ "Could not find Component source of event object "
+ + obj);
+ return;
+ }
+ Object joptionpaneObject = SwingUtilities.getAncestorOfClass(
+ JOptionPane.class, (Component) obj);
+ if (joptionpaneObject == null
+ || !(joptionpaneObject instanceof JOptionPane))
+ {
+ jalview.bin.Console.debug(
+ "Could not find JOptionPane ancestor of event object "
+ + obj);
+ return;
+ }
+ JOptionPane joptionpane = (JOptionPane) joptionpaneObject;
+ joptionpane.setValue(buttonAction);
+ if (action != null)
+ Executors.newSingleThreadExecutor().submit(action);
+ joptionpane.transferFocusBackward();
+ joptionpane.setVisible(false);
+ // put focus and raise parent window if possible, unless cancel or
+ // no button pressed
+ boolean raiseParent = (parentComponent != null);
+ if (buttonAction == JOptionPane.CANCEL_OPTION)
+ raiseParent = false;
+ if (optionType == JOptionPane.YES_NO_OPTION
+ && buttonAction == JOptionPane.NO_OPTION)
+ raiseParent = false;
+ if (raiseParent)
+ {
+ parentComponent.requestFocus();
+ if (parentComponent instanceof JInternalFrame)
+ {
+ JInternalFrame jif = (JInternalFrame) parentComponent;
+ jif.show();
+ jif.moveToFront();
+ jif.grabFocus();
+ }
+ else if (parentComponent instanceof Window)
+ {
+ Window w = (Window) parentComponent;
+ w.toFront();
+ w.requestFocus();
+ }
+ }
+ joptionpane.setVisible(false);
+ }
+ });
+
+ }
+ useButtons = true;
+ }
// use a JOptionPane as usual
int response = JOptionPane.showOptionDialog(parentComponent, message,
- title, optionType, messageType, icon, options, initialValue);
+ title, optionType, messageType, icon,
+ useButtons ? buttons : options,
+ useButtons ? initialValueButton : initialValue);
/*
* In Java, the response is returned to this thread and handled here;
* attached to the button press of the dialog. This means we can use
* a non-modal JDialog for the confirmation without blocking the GUI.
*/
+ JOptionPane joptionpane = new JOptionPane();
+ // Make button options
+ int[] buttonActions = { JvOptionPane.YES_OPTION,
+ JvOptionPane.NO_OPTION, JvOptionPane.CANCEL_OPTION };
- JDialog dialog = createDialog(parentComponent, message, title,
- optionType, messageType, icon, options, initialValue, modal,
- buttons);
- jalview.bin.Console.debug("About to setVisible(true)");
+ // we need the strings to make the buttons with actionEventListener
+ if (options == null)
+ {
+ ArrayList<String> options_default = new ArrayList<>();
+ options_default
+ .add(UIManager.getString("OptionPane.yesButtonText"));
+ if (optionType == JvOptionPane.YES_NO_OPTION
+ || optionType == JvOptionPane.YES_NO_CANCEL_OPTION)
+ {
+ options_default
+ .add(UIManager.getString("OptionPane.noButtonText"));
+ }
+ if (optionType == JvOptionPane.YES_NO_CANCEL_OPTION)
+ {
+ options_default
+ .add(UIManager.getString("OptionPane.cancelButtonText"));
+ }
+ options = options_default.toArray();
+ }
+
+ ArrayList<JButton> options_btns = new ArrayList<>();
+ Object initialValue_btn = null;
- if (!Platform.isJS()) // JalviewJS already uses callback, don't need to
- // add them here
++ if (!Platform.isJS()) // JalviewJS already uses callback, don't need to add them here
+ {
+ for (int i = 0; i < options.length && i < 3; i++)
+ {
+ Object o = options[i];
+ int buttonAction = buttonActions[i];
+ Runnable action = callbacks.get(buttonAction);
+ JButton jb = new JButton();
+ jb.setText((String) o);
+ jb.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ joptionpane.setValue(buttonAction);
+ if (action != null)
+ Executors.defaultThreadFactory().newThread(action).start();
+ // joptionpane.transferFocusBackward();
+ joptionpane.transferFocusBackward();
+ joptionpane.setVisible(false);
+ // put focus and raise parent window if possible, unless cancel
+ // button pressed
+ boolean raiseParent = (parentComponent != null);
+ if (buttonAction == JvOptionPane.CANCEL_OPTION)
+ raiseParent = false;
+ if (optionType == JvOptionPane.YES_NO_OPTION
+ && buttonAction == JvOptionPane.NO_OPTION)
+ raiseParent = false;
+ if (raiseParent)
+ {
+ parentComponent.requestFocus();
+ if (parentComponent instanceof JInternalFrame)
+ {
+ JInternalFrame jif = (JInternalFrame) parentComponent;
+ jif.show();
+ jif.moveToFront();
+ jif.grabFocus();
+ }
+ else if (parentComponent instanceof Window)
+ {
+ Window w = (Window) parentComponent;
+ w.toFront();
+ w.requestFocus();
+ }
+ }
+ joptionpane.setVisible(false);
+ }
+ });
+ options_btns.add(jb);
+ if (o.equals(initialValue))
+ initialValue_btn = jb;
+ }
+ }
+ joptionpane.setMessage(message);
+ joptionpane.setMessageType(messageType);
+ joptionpane.setOptionType(optionType);
+ joptionpane.setIcon(icon);
+ joptionpane.setOptions(
+ Platform.isJS() ? options : options_btns.toArray());
+ joptionpane.setInitialValue(
+ Platform.isJS() ? initialValue : initialValue_btn);
+
+ JDialog dialog = joptionpane.createDialog(parentComponent, title);
+ dialog.setIconImage(WindowIcons.logoIcon.getImage());
+ dialog.setModalityType(modal ? ModalityType.APPLICATION_MODAL
+ : ModalityType.MODELESS);
+ dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
- jalview.bin.Console.debug("Just setVisible(true)");
}
}
handleResponse(getMockResponse());
}
+ // need to set these separately so we can set the title bar icon later
+ this.setOptionType(yesNoCancelOption);
+ this.setMessageType(questionMessage);
+ this.setIcon(icon);
+ this.setInitialValue(initresponse);
+ this.setOptions(options);
+ this.setMessage(mainPanel);
+
ourOptions = Arrays.asList(options);
+ int response;
if (parentComponent != this)
{
- response = JOptionPane.showInternalOptionDialog(parentComponent,
- mainPanel, title, yesNoCancelOption, questionMessage, icon,
- options, initresponse);
+ JInternalFrame jif = this.createInternalFrame(parentComponent, title);
+ jif.setFrameIcon(WindowIcons.logoIcon);
+ jif.addInternalFrameListener(new InternalFrameListener()
+ {
+ @Override
+ public void internalFrameActivated(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameClosed(InternalFrameEvent arg0)
+ {
+ JvOptionPane.this.internalDialogHandleResponse();
+ }
+
+ @Override
+ public void internalFrameClosing(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameDeactivated(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameDeiconified(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameIconified(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameOpened(InternalFrameEvent arg0)
+ {
+ }
+ });
+ jif.setVisible(true);
+ startModal(jif);
+ return;
}
else
{
- response = JOptionPane.showOptionDialog(parentComponent, mainPanel,
- title, yesNoCancelOption, questionMessage, icon, options,
- initresponse);
+ JDialog dialog = this.createDialog(parentComponent, title);
+ dialog.setIconImage(WindowIcons.logoIcon.getImage());
+ dialog.setVisible(true); // blocking
+ this.internalDialogHandleResponse();
+ return;
}
+ }
+
+ private void internalDialogHandleResponse()
+ {
+ String responseString = (String) this.getValue();
+ int response = ourOptions.indexOf(responseString);
+
if (!Platform.isJS())
/**
* Java only
}
}
+ /*
@Override
public JvOptionPane setResponseHandler(Object response, Runnable action)
{
+ callbacks.put(response, new Callable<Void>()
+ {
+ @Override
+ public Void call()
+ {
+ action.run();
+ return null;
+ }
+ });
+ return this;
+ }
+ */
+ @Override
+ public JvOptionPane setResponseHandler(Object response,
+ Callable<Void> action)
+ {
callbacks.put(response, action);
return this;
}
/**
+ * showDialogOnTop will create a dialog that (attempts to) come to top of OS
+ * desktop windows
+ */
+ public static int showDialogOnTop(String label, String actionString,
+ int JOPTIONPANE_OPTION, int JOPTIONPANE_MESSAGETYPE)
+ {
+ // Ensure Jalview window is brought to front (primarily for Quit
+ // confirmation window to be visible)
+
+ // This method of raising the Jalview window is broken in java
+ // jalviewDesktop.setVisible(true);
+ // jalviewDesktop.toFront();
+
+ // A better hack which works is to create a new JFrame parent with
+ // setAlwaysOnTop(true)
+ JFrame dialogParent = new JFrame();
+ dialogParent.setAlwaysOnTop(true);
+
+ int answer = JOptionPane.showConfirmDialog(dialogParent, label,
+ actionString, JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE);
+
+ dialogParent.setAlwaysOnTop(false);
+ dialogParent.dispose();
+
+ return answer;
+ }
+
+ public void showDialogOnTopAsync(String label, String actionString,
+ int JOPTIONPANE_OPTION, int JOPTIONPANE_MESSAGETYPE, Icon icon,
+ Object[] options, Object initialValue, boolean modal)
+ {
+ showDialogOnTopAsync(new JFrame(), label, actionString,
+ JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE, icon, options,
+ initialValue, modal);
+ }
+
+ public void showDialogOnTopAsync(JFrame dialogParent, Object label,
+ String actionString, int JOPTIONPANE_OPTION,
+ int JOPTIONPANE_MESSAGETYPE, Icon icon, Object[] options,
+ Object initialValue, boolean modal)
+ {
+ showDialogOnTopAsync(dialogParent, label, actionString,
+ JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE, icon, options,
+ initialValue, modal, null);
+ }
+
+ public void showDialogOnTopAsync(JFrame dialogParent, Object label,
+ String actionString, int JOPTIONPANE_OPTION,
+ int JOPTIONPANE_MESSAGETYPE, Icon icon, Object[] options,
+ Object initialValue, boolean modal, JButton[] buttons)
+ {
+ // Ensure Jalview window is brought to front (primarily for Quit
+ // confirmation window to be visible)
+
+ // This method of raising the Jalview window is broken in java
+ // jalviewDesktop.setVisible(true);
+ // jalviewDesktop.toFront();
+
+ // A better hack which works is to create a new JFrame parent with
+ // setAlwaysOnTop(true)
+ dialogParent.setAlwaysOnTop(true);
+ parentComponent = dialogParent;
+
+ showDialog(label, actionString, JOPTIONPANE_OPTION,
+ JOPTIONPANE_MESSAGETYPE, icon, options, initialValue, modal,
+ buttons);
+
+ dialogParent.setAlwaysOnTop(false);
+ dialogParent.dispose();
+ }
+
+ /**
* JalviewJS signals option selection by a property change event for the
* option e.g. "OK". This methods responds to that by running the response
* action that corresponds to that option.
{
return;
}
- Runnable action = callbacks.get(response);
+ Callable<Void> action = callbacks.get(response);
if (action != null)
{
- action.run();
- parentComponent.requestFocus();
+ try
+ {
+ action.call();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ if (parentComponent != null)
+ parentComponent.requestFocus();
+ }
+ }
+
+ /**
+ * Create a non-modal confirm dialog
+ */
+ public JDialog createDialog(Component parentComponent, Object message,
+ String title, int optionType, int messageType, Icon icon,
+ Object[] options, Object initialValue, boolean modal)
+ {
+ return createDialog(parentComponent, message, title, optionType,
+ messageType, icon, options, initialValue, modal, null);
+ }
+
+ public JDialog createDialog(Component parentComponent, Object message,
+ String title, int optionType, int messageType, Icon icon,
+ Object[] options, Object initialValue, boolean modal,
+ JButton[] buttons)
+ {
+ JButton[] optionsButtons = null;
+ Object initialValueButton = null;
+ JOptionPane joptionpane = new JOptionPane();
+ // Make button options
+ int[] buttonActions = { JOptionPane.YES_OPTION, JOptionPane.NO_OPTION,
+ JOptionPane.CANCEL_OPTION };
+
+ // we need the strings to make the buttons with actionEventListener
+ if (options == null)
+ {
+ ArrayList<String> options_default = new ArrayList<>();
+ options_default.add(UIManager.getString("OptionPane.yesButtonText"));
+ if (optionType == JOptionPane.YES_NO_OPTION
+ || optionType == JOptionPane.YES_NO_CANCEL_OPTION)
+ {
+ options_default.add(UIManager.getString("OptionPane.noButtonText"));
+ }
+ if (optionType == JOptionPane.YES_NO_CANCEL_OPTION)
+ {
+ options_default
+ .add(UIManager.getString("OptionPane.cancelButtonText"));
+ }
+ options = options_default.toArray();
}
+ if (!Platform.isJS()) // JalviewJS already uses callback, don't need to
+ // add them here
+ {
+ if (((optionType == JOptionPane.YES_OPTION
+ || optionType == JOptionPane.NO_OPTION
+ || optionType == JOptionPane.CANCEL_OPTION
+ || optionType == JOptionPane.OK_OPTION
+ || optionType == JOptionPane.DEFAULT_OPTION)
+ && options.length < 1)
+ || ((optionType == JOptionPane.YES_NO_OPTION
+ || optionType == JOptionPane.OK_CANCEL_OPTION)
+ && options.length < 2)
+ || (optionType == JOptionPane.YES_NO_CANCEL_OPTION
+ && options.length < 3))
+ {
+ jalview.bin.Console
+ .debug("JvOptionPane: not enough options for dialog type");
+ }
+ optionsButtons = new JButton[options.length];
+ for (int i = 0; i < options.length && i < 3; i++)
+ {
+ Object o = options[i];
+ int buttonAction = buttonActions[i];
+ Callable<Void> action = callbacks.get(buttonAction);
+ JButton jb;
+ if (buttons != null && buttons.length > i && buttons[i] != null)
+ {
+ jb = buttons[i];
+ }
+ else
+ {
+ jb = new JButton();
+ }
+ jb.setText((String) o);
+ jb.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ joptionpane.setValue(buttonAction);
+ if (action != null)
+ Executors.newSingleThreadExecutor().submit(action);
+ // joptionpane.transferFocusBackward();
+ joptionpane.transferFocusBackward();
+ joptionpane.setVisible(false);
+ // put focus and raise parent window if possible, unless cancel
+ // button pressed
+ boolean raiseParent = (parentComponent != null);
+ if (buttonAction == JOptionPane.CANCEL_OPTION)
+ raiseParent = false;
+ if (optionType == JOptionPane.YES_NO_OPTION
+ && buttonAction == JOptionPane.NO_OPTION)
+ raiseParent = false;
+ if (raiseParent)
+ {
+ parentComponent.requestFocus();
+ if (parentComponent instanceof JInternalFrame)
+ {
+ JInternalFrame jif = (JInternalFrame) parentComponent;
+ jif.show();
+ jif.moveToFront();
+ jif.grabFocus();
+ }
+ else if (parentComponent instanceof Window)
+ {
+ Window w = (Window) parentComponent;
+ w.toFront();
+ w.requestFocus();
+ }
+ }
+ joptionpane.setVisible(false);
+ }
+ });
+ optionsButtons[i] = jb;
+ if (o.equals(initialValue))
+ initialValueButton = jb;
+ }
+ }
+ joptionpane.setMessage(message);
+ joptionpane.setMessageType(messageType);
+ joptionpane.setOptionType(optionType);
+ joptionpane.setIcon(icon);
+ joptionpane.setOptions(Platform.isJS() ? options : optionsButtons);
+ joptionpane.setInitialValue(
+ Platform.isJS() ? initialValue : initialValueButton);
+
+ JDialog dialog = joptionpane.createDialog(parentComponent, title);
+ dialog.setModalityType(
+ modal ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS);
+ dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ return dialog;
+ }
+
+ /**
+ * Utility to programmatically click a button on a JOptionPane (as a JFrame)
+ *
+ * returns true if button was found
+ */
+ public static boolean clickButton(JFrame frame, int buttonType)
+ {
+
+ return false;
}
+
+ /**
+ * This helper method makes the JInternalFrame wait until it is notified by an
+ * InternalFrameClosing event. This method also adds the given JOptionPane to
+ * the JInternalFrame and sizes it according to the JInternalFrame's preferred
+ * size.
+ *
+ * @param f
+ * The JInternalFrame to make modal.
+ */
+ private static void startModal(JInternalFrame f)
+ {
+ // We need to add an additional glasspane-like component directly
+ // below the frame, which intercepts all mouse events that are not
+ // directed at the frame itself.
+ JPanel modalInterceptor = new JPanel();
+ modalInterceptor.setOpaque(false);
+ JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f);
+ lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue());
+ modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight());
+ modalInterceptor.addMouseListener(new MouseAdapter()
+ {
+ });
+ modalInterceptor.addMouseMotionListener(new MouseMotionAdapter()
+ {
+ });
+ lp.add(modalInterceptor);
+ f.toFront();
+
+ // We need to explicitly dispatch events when we are blocking the event
+ // dispatch thread.
+ EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ try
+ {
+ while (!f.isClosed())
+ {
+ if (EventQueue.isDispatchThread())
+ {
+ // The getNextEventMethod() issues wait() when no
+ // event is available, so we don't need do explicitly wait().
+ AWTEvent ev = queue.getNextEvent();
+ // This mimics EventQueue.dispatchEvent(). We can't use
+ // EventQueue.dispatchEvent() directly, because it is
+ // protected, unfortunately.
+ if (ev instanceof ActiveEvent)
+ ((ActiveEvent) ev).dispatch();
+ else if (ev.getSource() instanceof Component)
+ ((Component) ev.getSource()).dispatchEvent(ev);
+ else if (ev.getSource() instanceof MenuComponent)
+ ((MenuComponent) ev.getSource()).dispatchEvent(ev);
+ // Other events are ignored as per spec in
+ // EventQueue.dispatchEvent
+ }
+ else
+ {
+ // Give other threads a chance to become active.
+ Thread.yield();
+ }
+ }
+ } catch (InterruptedException ex)
+ {
+ // If we get interrupted, then leave the modal state.
+ } finally
+ {
+ // Clean up the modal interceptor.
+ lp.remove(modalInterceptor);
+
+ // Remove the internal frame from its parent, so it is no longer
+ // lurking around and clogging memory.
+ Container parent = f.getParent();
+ if (parent != null)
+ parent.remove(f);
+ }
+ }
}
public StructureViewerBase()
{
super();
+ setFrameIcon(WindowIcons.structureIcon);
}
/**
if (confirm == JvOptionPane.CANCEL_OPTION
|| confirm == JvOptionPane.CLOSED_OPTION)
{
+ // abort possible quit handling if CANCEL chosen
+ if (confirm == JvOptionPane.CANCEL_OPTION)
+ QuitHandler.abortQuit();
return;
}
forceClose = confirm == JvOptionPane.YES_OPTION;
{
colorChooser.getSelectionModel().addChangeListener(this);
frame = new JInternalFrame();
+ frame.setFrameIcon(WindowIcons.logoIcon);
frame.setContentPane(this);
Desktop.addInternalFrame(frame,
MessageManager.getString("label.user_defined_colours"),
chooser.setDialogTitle(
MessageManager.getString("label.load_colour_scheme"));
chooser.setToolTipText(MessageManager.getString("action.load"));
- chooser.setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
- {
- File choice = chooser.getSelectedFile();
- Cache.setProperty(LAST_DIRECTORY, choice.getParent());
-
- UserColourScheme ucs = ColourSchemeLoader
- .loadColourScheme(choice.getAbsolutePath());
- Color[] colors = ucs.getColours();
- schemeName.setText(ucs.getSchemeName());
+ chooser.setResponseHandler(0, () -> {
+ File choice = chooser.getSelectedFile();
+ Cache.setProperty(LAST_DIRECTORY, choice.getParent());
- if (ucs.getLowerCaseColours() != null)
- {
- caseSensitive.setSelected(true);
- lcaseColour.setEnabled(true);
- resetButtonPanel(true);
- for (int i = 0; i < lowerCaseButtons.size(); i++)
- {
- JButton button = lowerCaseButtons.get(i);
- button.setBackground(ucs.getLowerCaseColours()[i]);
- }
- }
- else
- {
- caseSensitive.setSelected(false);
- lcaseColour.setEnabled(false);
- resetButtonPanel(false);
- }
+ UserColourScheme ucs = ColourSchemeLoader
+ .loadColourScheme(choice.getAbsolutePath());
+ Color[] colors = ucs.getColours();
+ schemeName.setText(ucs.getSchemeName());
- for (int i = 0; i < upperCaseButtons.size(); i++)
+ if (ucs.getLowerCaseColours() != null)
+ {
+ caseSensitive.setSelected(true);
+ lcaseColour.setEnabled(true);
+ resetButtonPanel(true);
+ for (int i = 0; i < lowerCaseButtons.size(); i++)
{
- JButton button = upperCaseButtons.get(i);
- button.setBackground(colors[i]);
+ JButton button = lowerCaseButtons.get(i);
+ button.setBackground(ucs.getLowerCaseColours()[i]);
}
+ }
+ else
+ {
+ caseSensitive.setSelected(false);
+ lcaseColour.setEnabled(false);
+ resetButtonPanel(false);
+ }
- addNewColourScheme(choice.getPath());
+ for (int i = 0; i < upperCaseButtons.size(); i++)
+ {
+ JButton button = upperCaseButtons.get(i);
+ button.setBackground(colors[i]);
}
+
+ addNewColourScheme(choice.getPath());
+ return null;
});
chooser.showOpenDialog(this);
//////////////////////////////////////////////////////////////////
package jalview.io;
++import jalview.bin.Cache;
++import jalview.gui.JvOptionPane;
++import jalview.util.MessageManager;
++import jalview.util.Platform;
++import jalview.util.dialogrunner.DialogRunnerI;
++
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
+import java.util.concurrent.Callable;
import javax.swing.BoxLayout;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JCheckBox;
+ import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JList;
+import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SpringLayout;
import jalview.bin.Cache;
import jalview.gui.JvOptionPane;
+ import jalview.gui.WindowIcons;
import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.util.dialogrunner.DialogRunnerI;
{
private static final long serialVersionUID = 1L;
- private Map<Object, Runnable> callbacks = new HashMap<>();
+ private Map<Object, Callable> callbacks = new HashMap<>();
File selectedFile = null;
if (selectedFile.exists())
{
- int confirm = JvOptionPane.showConfirmDialog(this,
- MessageManager.getString("label.overwrite_existing_file"),
- MessageManager.getString("label.file_already_exists"),
- JvOptionPane.YES_NO_OPTION);
+ int confirm = Cache.getDefault("CONFIRM_OVERWRITE_FILE", true)
+ ? JvOptionPane.showConfirmDialog(this,
+ MessageManager
+ .getString("label.overwrite_existing_file"),
+ MessageManager.getString("label.file_already_exists"),
+ JvOptionPane.YES_NO_OPTION)
+ : JOptionPane.YES_OPTION;
if (confirm != JvOptionPane.YES_OPTION)
{
}
+ /*
+ @Override
+ public JalviewFileChooser setResponseHandler(Object response,
+ Runnable action)
+ {
+ callbacks.put(response, new Callable<Void>()
+ {
+ @Override
+ public Void call()
+ {
+ action.run();
+ return null;
+ }
+ });
+ return this;
+ }
+ */
+
@Override
- public DialogRunnerI setResponseHandler(Object response, Runnable action)
+ public DialogRunnerI setResponseHandler(Object response, Callable action)
{
callbacks.put(response, action);
return this;
{
return;
}
- Runnable action = callbacks.get(response);
+ Callable action = callbacks.get(response);
if (action != null)
{
- action.run();
+ try
+ {
+ action.call();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
}
}
break;
}
}
+
+ @Override
+ protected JDialog createDialog(Component parent) throws HeadlessException
+ {
+ JDialog dialog = super.createDialog(parent);
+ dialog.setIconImage(WindowIcons.logoIcon.getImage());
+ return dialog;
+ }
+
}