action.force_quit = Force Quit
label.quit_jalview = Are you sure you want to quit Jalview?
label.unsaved_changes = There are unsaved changes.
-label.save_in_progress = Some files are still saving.
+label.save_in_progress = Some files are still saving:
label.unknown = Unknown
action.wait = Wait
action.cancel_quit = Cancel quit
action.force_quit = Forzar la salida
label.quit_jalview = ¿Estás seguro de que quieres salir de Jalview?
label.unsaved_changes = Hay cambios sin guardar.
-label.save_in_progress = Algunos archivos aún se están guardando.
+label.save_in_progress = Algunos archivos aún se están guardando:
label.unknown = desconocido
action.wait = Espere
action.cancel_quit = Cancelar la salida
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);
}
*/
package jalview.gui;
-import jalview.api.AlignExportSettingsI;
-import jalview.api.AlignViewportI;
-import jalview.io.FileFormatI;
-import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
+import java.util.concurrent.Callable;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
+import jalview.api.AlignExportSettingsI;
+import jalview.api.AlignViewportI;
+import jalview.io.FileFormatI;
+import jalview.util.MessageManager;
+
/**
* A dialog that allows the user to specify whether to include hidden columns or
* sequences in an alignment export, and possibly features, annotations and
*
* @param action
*/
- public void setResponseAction(Object response, Runnable action)
+ public void setResponseAction(Object response, Callable action)
{
dialog.setResponseHandler(response, action);
}
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;
}
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)
- {
- Console.trace(
- "ALIGNFRAME making backupfiles object for " + file);
- backupfiles = new BackupFiles(file);
- }
- try
- {
- String tempFilePath = doBackup ? backupfiles.getTempFilePath()
- : file;
- Console.trace("ALIGNFRAME setting PrintWriter");
- PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
+ 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)
+ if (backupfiles != null)
{
- lastSaveSuccessful = false;
- Console.error(
- "ALIGNFRAME Something unexpected happened writing the temp file");
- Console.error(ex.getMessage());
- Console.debug(Cache.getStackTraceString(ex));
+ Console.trace("ALIGNFRAME about to write to temp file "
+ + backupfiles.getTempFilePath());
}
- 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");
- }
+ 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));
+ }
- Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
- if (lastSaveSuccessful)
- {
- AlignFrame.this.getViewport().setSavedUpToDate(true);
- }
+ 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();
+ }
}
}
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);
*/
package jalview.gui;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.swing.JInternalFrame;
+
import jalview.analysis.AlignmentUtils;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.api.AlignViewportI;
import jalview.viewmodel.AlignmentViewport;
import jalview.ws.params.AutoCalcSetting;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.List;
-
-import javax.swing.JInternalFrame;
-
/**
* DOCUMENT ME!
*
* in reverse order)
*/
JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop)
- .setResponseHandler(0, new Runnable()
- {
- @Override
- public void run()
- {
- addDataToAlignment(al);
- }
- }).setResponseHandler(1, new Runnable()
- {
- @Override
- public void run()
- {
- us.openLinkedAlignmentAs(al, title, true);
- }
- }).setResponseHandler(2, new Runnable()
- {
- @Override
- public void run()
- {
- us.openLinkedAlignmentAs(al, title, false);
- }
+ .setResponseHandler(0, () -> {
+ addDataToAlignment(al);
+ return null;
+ }).setResponseHandler(1, () -> {
+ us.openLinkedAlignmentAs(al, title, true);
+ return null;
+ }).setResponseHandler(2, () -> {
+ us.openLinkedAlignmentAs(al, title, false);
+ return null;
});
dialog.showDialog(question,
MessageManager.getString("label.open_split_window"),
*/
package jalview.gui;
-import java.util.Locale;
-
-import jalview.analysis.AlignSeq;
-import jalview.analysis.AlignmentUtils;
-import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.io.FileFormat;
-import jalview.io.FormatAdapter;
-import jalview.util.Comparison;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
+import java.util.Locale;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
+import jalview.analysis.AlignSeq;
+import jalview.analysis.AlignmentUtils;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
/**
* The panel that holds the labels for alignment annotations, providing
* tooltips, context menus, drag to reorder rows, and drag to adjust panel
EditNameDialog dialog = new EditNameDialog(annotation.label,
annotation.description, name, description);
- dialog.showDialog(ap.alignFrame, title, new Runnable()
- {
- @Override
- public void run()
+ dialog.showDialog(ap.alignFrame, title, () -> {
+ annotation.label = dialog.getName();
+ String text = dialog.getDescription();
+ if (text != null && text.length() == 0)
{
- annotation.label = dialog.getName();
- String text = dialog.getDescription();
- if (text != null && text.length() == 0)
- {
- text = null;
- }
- annotation.description = text;
- if (addNew)
- {
- ap.av.getAlignment().addAnnotation(annotation);
- ap.av.getAlignment().setAnnotationIndex(annotation, 0);
- }
- ap.refresh(true);
+ text = null;
}
+ annotation.description = text;
+ if (addNew)
+ {
+ ap.av.getAlignment().addAnnotation(annotation);
+ ap.av.getAlignment().setAnnotationIndex(annotation, 0);
+ }
+ ap.refresh(true);
+ return null;
});
}
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame = initFrame("Java Console", screenSize.width / 2,
screenSize.height / 2, -1, -1);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
initConsole(true);
}
{
}
}
+ /*
if (!frame.isVisible())
{
frame.dispose();
}
+ */
// System.exit(0);
}
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;
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)
{
- QResponse qresponse = desktopQuit();
- if (qresponse != QResponse.CANCEL_QUIT)
- {
- instance.dispose();
- }
+ QuitHandler.QResponse ret = desktopQuit(true, true); // ui, disposeFlag
}
});
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");
/*
* Check with user and saving files before actually quitting
*/
- public QResponse desktopQuit()
+ public void desktopQuit()
{
- return desktopQuit(true);
+ desktopQuit(true, false);
}
- public QResponse desktopQuit(boolean ui)
+ public QuitHandler.QResponse desktopQuit(boolean ui, boolean disposeFlag)
{
- QuitHandler.QResponse qresponse = QuitHandler.getQuitResponse(ui);
+ 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 (qresponse == QResponse.CANCEL_QUIT)
- {
- return qresponse;
- }
+ if (jconsole != null)
+ {
+ storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
+ jconsole.stopConsole();
+ }
- 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 (jvnews != null)
+ {
+ storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
- if (jconsole != null)
- {
- storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
- jconsole.stopConsole();
- }
- if (jvnews != null)
- {
- storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
+ }
- }
- if (dialogExecutor != null)
- {
- dialogExecutor.shutdownNow();
- }
- closeAll_actionPerformed(null);
+ if (dialogExecutor != null)
+ {
+ dialogExecutor.shutdownNow();
+ }
- if (groovyConsole != null)
- {
- // suppress a possible repeat prompt to save script
- groovyConsole.setDirty(false);
- groovyConsole.exit();
- }
+ closeAll_actionPerformed(null);
- if (qresponse == QResponse.FORCE_QUIT)
- {
- // note that shutdown hook will not be run
- jalview.bin.Console.debug("Force Quit selected by user");
- Runtime.getRuntime().halt(0);
- }
+ 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");
- jalview.bin.Console.debug("Quit selected by user");
- quit();
+ return QuitHandler.gotQuitResponse();
+ };
- // unlikely to reach here!
- return QResponse.QUIT;
+ return QuitHandler.getQuitResponse(ui, doDesktopQuit, doDesktopQuit,
+ QuitHandler.defaultCancelQuit);
}
/**
// 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)
{
- QResponse qresponse = desktopQuit();
- if (qresponse == QResponse.CANCEL_QUIT)
- {
- jalview.bin.Console
- .debug("Desktop: Quit action cancelled by user");
- }
+ desktopQuit();
}
});
}
*/
package jalview.gui;
-import jalview.util.MessageManager;
-
import java.awt.FlowLayout;
import java.awt.Font;
+import java.util.concurrent.Callable;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
+import jalview.util.MessageManager;
+
/**
* A dialog where a name and description may be edited
*/
*
* @param action
*/
- public void showDialog(JComponent parent, String title, Runnable action)
+ public void showDialog(JComponent parent, String title, Callable action)
{
Object[] options = new Object[] { MessageManager.getString("action.ok"),
MessageManager.getString("action.cancel") };
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Callable;
import javax.swing.JComboBox;
import javax.swing.JLabel;
*/
public void showDialog()
{
- Runnable okAction = forCreate ? getCreateAction() : getAmendAction();
- Runnable cancelAction = getCancelAction();
+ Callable<Void> okAction = forCreate ? getCreateAction()
+ : getAmendAction();
+ Callable<Void> cancelAction = getCancelAction();
/*
* set dialog action handlers for OK (create/Amend) and Cancel options
*
* @return
*/
- protected Runnable getCancelAction()
+ protected Callable getCancelAction()
{
- Runnable okAction = new Runnable()
- {
- @Override
- public void run()
- {
- ap.highlightSearchResults(null);
- ap.paintAlignment(false, false);
- }
+ Callable<Void> okAction = () -> {
+ ap.highlightSearchResults(null);
+ ap.paintAlignment(false, false);
+ return null;
};
return okAction;
}
*
* @return
*/
- protected Runnable getCreateAction()
+ protected Callable getCreateAction()
{
- Runnable okAction = new Runnable()
+ Callable<Void> okAction = new Callable()
{
boolean useLastDefaults = features.get(0).getType() == null;
@Override
- public void run()
+ public Void call()
{
final String enteredType = name.getText().trim();
final String enteredGroup = group.getText().trim();
repaintPanel();
}
+ return null;
}
};
return okAction;
*
* @return
*/
- protected Runnable getDeleteAction()
+ protected Callable getDeleteAction()
{
- Runnable deleteAction = new Runnable()
- {
- @Override
- public void run()
- {
- SequenceFeature sf = features.get(featureIndex);
- sequences.get(0).getDatasetSequence().deleteFeature(sf);
- fr.featuresAdded();
- ap.getSeqPanel().seqCanvas.highlightSearchResults(null);
- ap.paintAlignment(true, true);
- }
+ Callable<Void> deleteAction = () -> {
+ SequenceFeature sf = features.get(featureIndex);
+ sequences.get(0).getDatasetSequence().deleteFeature(sf);
+ fr.featuresAdded();
+ ap.getSeqPanel().seqCanvas.highlightSearchResults(null);
+ ap.paintAlignment(true, true);
+ return null;
};
return deleteAction;
}
*
* @return
*/
- protected Runnable getAmendAction()
+ protected Callable getAmendAction()
{
- Runnable okAction = new Runnable()
+ Callable<Void> okAction = new Callable()
{
boolean useLastDefaults = features.get(0).getType() == null;
String featureGroup = group.getText();
@Override
- public void run()
+ public Void call()
{
final String enteredType = name.getText().trim();
final String enteredGroup = group.getText().trim();
fr.featuresAdded();
}
repaintPanel();
+ return null;
}
};
return okAction;
*/
package jalview.gui;
-import java.util.Locale;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
-import javax.swing.JCheckBoxMenuItem;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
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.Component;
+import java.awt.Graphics;
+import java.io.File;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.io.JalviewFileChooser;
import jalview.util.MessageManager;
import jalview.util.Platform;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.io.File;
-import java.util.concurrent.atomic.AtomicBoolean;
-
/**
* A class that marshals steps in exporting a view in image graphics format
* <ul>
&& !Jalview.isHeadlessMode())
{
final File chosenFile = file;
- Runnable okAction = new Runnable()
- {
- @Override
- public void run()
- {
- exportImage(chosenFile, !textSelected.get(), width, height,
- messageId);
- }
+ Callable<Void> okAction = () -> {
+ exportImage(chosenFile, !textSelected.get(), width, height,
+ messageId);
+ return null;
};
LineartOptions epsOption = new LineartOptions(TYPE.EPS.getName(),
textSelected);
- epsOption.setResponseAction(1, new Runnable()
+ epsOption.setResponseAction(1, new Callable<Void>()
{
@Override
- public void run()
+ public Void call()
{
setStatus(MessageManager.formatMessage(
"status.cancelled_image_export_operation",
imageType.getName()), messageId);
+ return null;
}
});
epsOption.setResponseAction(0, okAction);
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.JOptionPane;
import javax.swing.JPanel;
{
private static final long serialVersionUID = -3019167117756785229L;
- private static Object mockResponse = JvOptionPane.CANCEL_OPTION;
+ private static Object mockResponse = JOptionPane.CANCEL_OPTION;
private static boolean interactiveMode = true;
private Component parentComponent;
- private Map<Object, Runnable> callbacks = new HashMap<>();
+ private Map<Object, Callable> callbacks = new HashMap<>();
/*
* JalviewJS reports user choice in the dialog as the selected
}
switch (optionType)
{
- case JvOptionPane.YES_NO_CANCEL_OPTION:
+ case JOptionPane.YES_NO_CANCEL_OPTION:
// FeatureRenderer amendFeatures ?? TODO ??
// Chimera close
// PromptUserConfig
// $FALL-THROUGH$
default:
- case JvOptionPane.YES_NO_OPTION:
+ case JOptionPane.YES_NO_OPTION:
// PromptUserConfig usage stats
// for now treated as "OK CANCEL"
// $FALL-THROUGH$
- case JvOptionPane.OK_CANCEL_OPTION:
+ case JOptionPane.OK_CANCEL_OPTION:
// will fall back to simple HTML
return JOptionPane.showConfirmDialog(parentComponent, message, title,
optionType);
}
switch (optionType)
{
- case JvOptionPane.YES_NO_CANCEL_OPTION:
+ case JOptionPane.YES_NO_CANCEL_OPTION:
// ColourMenuHelper.addMenuItmers.offerRemoval TODO
- case JvOptionPane.YES_NO_OPTION:
+ case JOptionPane.YES_NO_OPTION:
// UserDefinedColoursSave -- relevant? TODO
// $FALL-THROUGH$
default:
- case JvOptionPane.OK_CANCEL_OPTION:
+ case JOptionPane.OK_CANCEL_OPTION:
// EditNameDialog --- uses panel for messsage TODO
}
switch (optionType)
{
- case JvOptionPane.YES_NO_CANCEL_OPTION:
- case JvOptionPane.YES_NO_OPTION:
+ case JOptionPane.YES_NO_CANCEL_OPTION:
+ case JOptionPane.YES_NO_OPTION:
// UserQuestionanaireCheck
// VamsasApplication
// $FALL-THROUGH$
default:
- case JvOptionPane.OK_CANCEL_OPTION:
+ case JOptionPane.OK_CANCEL_OPTION:
// will fall back to simple HTML
return JOptionPane.showConfirmDialog(parentComponent, message, title,
optionType, messageType);
}
switch (optionType)
{
- case JvOptionPane.YES_NO_CANCEL_OPTION:
- case JvOptionPane.YES_NO_OPTION:
+ case JOptionPane.YES_NO_CANCEL_OPTION:
+ case JOptionPane.YES_NO_OPTION:
//$FALL-THROUGH$
default:
- case JvOptionPane.OK_CANCEL_OPTION:
+ case JOptionPane.OK_CANCEL_OPTION:
// Preferences editLink/newLink
return JOptionPane.showConfirmDialog(parentComponent, message, title,
optionType, messageType, icon);
public static void resetMock()
{
- setMockResponse(JvOptionPane.CANCEL_OPTION);
+ setMockResponse(JOptionPane.CANCEL_OPTION);
setInteractiveMode(true);
}
{
switch (messageType)
{
- case JvOptionPane.WARNING_MESSAGE:
+ case JOptionPane.WARNING_MESSAGE:
prefix = "WARNING! ";
break;
- case JvOptionPane.ERROR_MESSAGE:
+ case JOptionPane.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);
* 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 };
-
- // 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
- {
- 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.setModalityType(modal ? ModalityType.APPLICATION_MODAL
- : ModalityType.MODELESS);
- dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ JDialog dialog = this.createDialog(parentComponent, message, title,
+ optionType, messageType, icon, options, initialValue, modal);
+ jalview.bin.Console.debug("About to setVisible(true)");
dialog.setVisible(true);
+ jalview.bin.Console.debug("Just setVisible(true)");
}
}
}
}
+ /*
@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 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);
+ jalview.bin.Console.debug("*********** BEFORE dialogParent.dispose()");
+ dialogParent.dispose();
+ jalview.bin.Console.debug("*********** BEFORE 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)
+ {
+ // 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);
+ parentComponent = dialogParent;
+
+ showDialog(label, actionString, JOPTIONPANE_OPTION,
+ JOPTIONPANE_MESSAGETYPE, icon, options, initialValue, modal);
+
+ 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, String message,
+ String title, int optionType, int messageType, Icon icon,
+ Object[] options, Object initialValue, boolean modal)
+ {
+ 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();
}
+ 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 (((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");
+ }
+ for (int i = 0; i < options.length && i < 3; i++)
+ {
+ Object o = options[i];
+ int buttonAction = buttonActions[i];
+ Callable 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.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);
+ }
+ });
+ 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.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;
}
}
*/
package jalview.gui;
-import jalview.bin.Cache;
-import jalview.util.MessageManager;
-
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
+import jalview.bin.Cache;
+import jalview.util.MessageManager;
+
/**
* A dialog where the user may choose Text or Lineart rendering, and optionally
* save this as a preference ("Don't ask me again")
*
* @param action
*/
- public void setResponseAction(Object response, Runnable action)
+ public void setResponseAction(Object response, Callable action)
{
dialog.setResponseHandler(response, action);
}
*/
package jalview.gui;
-import java.util.Locale;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
MessageManager.getString("label.group_description"));
dialog.showDialog(ap.alignFrame,
MessageManager.getString("label.edit_group_name_description"),
- new Runnable()
- {
- @Override
- public void run()
- {
- sg.setName(dialog.getName());
- sg.setDescription(dialog.getDescription());
- refresh();
- }
+ () -> {
+ sg.setName(dialog.getName());
+ sg.setDescription(dialog.getDescription());
+ refresh();
+ return null;
});
}
sequence.getDescription(),
MessageManager.getString("label.sequence_name"),
MessageManager.getString("label.sequence_description"));
- dialog.showDialog(ap.alignFrame, MessageManager.getString(
- "label.edit_sequence_name_description"), new Runnable()
- {
- @Override
- public void run()
+ dialog.showDialog(ap.alignFrame, MessageManager
+ .getString("label.edit_sequence_name_description"), () -> {
+ if (dialog.getName() != null)
{
- if (dialog.getName() != null)
+ if (dialog.getName().indexOf(" ") > -1)
{
- if (dialog.getName().indexOf(" ") > -1)
- {
- JvOptionPane.showMessageDialog(ap,
- MessageManager.getString(
- "label.spaces_converted_to_underscores"),
- MessageManager.getString(
- "label.no_spaces_allowed_sequence_name"),
- JvOptionPane.WARNING_MESSAGE);
- }
- sequence.setName(dialog.getName().replace(' ', '_'));
- ap.paintAlignment(false, false);
+ JvOptionPane.showMessageDialog(ap,
+ MessageManager.getString(
+ "label.spaces_converted_to_underscores"),
+ MessageManager.getString(
+ "label.no_spaces_allowed_sequence_name"),
+ JvOptionPane.WARNING_MESSAGE);
}
- sequence.setDescription(dialog.getDescription());
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ sequence.setName(dialog.getName().replace(' ', '_'));
+ ap.paintAlignment(false, false);
}
+ sequence.setDescription(dialog.getDescription());
+ ap.av.firePropertyChange("alignment", null,
+ ap.av.getAlignment().getSequences());
+ return null;
});
}
seq.getSequenceAsString(sg.getStartRes(), sg.getEndRes() + 1),
null, MessageManager.getString("label.edit_sequence"), null);
dialog.showDialog(ap.alignFrame,
- MessageManager.getString("label.edit_sequence"),
- new Runnable()
- {
- @Override
- public void run()
- {
- EditCommand editCommand = new EditCommand(
- MessageManager.getString("label.edit_sequences"),
- Action.REPLACE,
- dialog.getName().replace(' ',
- ap.av.getGapCharacter()),
- sg.getSequencesAsArray(
- ap.av.getHiddenRepSequences()),
- sg.getStartRes(), sg.getEndRes() + 1,
- ap.av.getAlignment());
- ap.alignFrame.addHistoryItem(editCommand);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
- }
+ MessageManager.getString("label.edit_sequence"), () -> {
+ EditCommand editCommand = new EditCommand(
+ MessageManager.getString("label.edit_sequences"),
+ Action.REPLACE,
+ dialog.getName().replace(' ',
+ ap.av.getGapCharacter()),
+ sg.getSequencesAsArray(
+ ap.av.getHiddenRepSequences()),
+ sg.getStartRes(), sg.getEndRes() + 1,
+ ap.av.getAlignment());
+ ap.alignFrame.addHistoryItem(editCommand);
+ ap.av.firePropertyChange("alignment", null,
+ ap.av.getAlignment().getSequences());
+ return null;
});
}
}
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
+import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import javax.swing.JCheckBox;
};
// fetch db refs if OK pressed
- final Runnable discoverCanonicalDBrefs = new Runnable()
- {
- @Override
- public void run()
+ final Callable discoverCanonicalDBrefs = () -> {
+ btn_queryTDB.setEnabled(false);
+ populateSeqsWithoutSourceDBRef();
+
+ final int y = seqsWithoutSourceDBRef.size();
+ if (y > 0)
{
- btn_queryTDB.setEnabled(false);
- populateSeqsWithoutSourceDBRef();
+ final SequenceI[] seqWithoutSrcDBRef = seqsWithoutSourceDBRef
+ .toArray(new SequenceI[y]);
+ DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef,
+ progressBar, new DbSourceProxy[]
+ { new jalview.ws.dbsources.Uniprot() }, null, false);
+ dbRefFetcher.addListener(afterDbRefFetch);
+ // ideally this would also gracefully run with callbacks
- final int y = seqsWithoutSourceDBRef.size();
- if (y > 0)
- {
- final SequenceI[] seqWithoutSrcDBRef = seqsWithoutSourceDBRef
- .toArray(new SequenceI[y]);
- DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef,
- progressBar, new DbSourceProxy[]
- { new jalview.ws.dbsources.Uniprot() }, null, false);
- dbRefFetcher.addListener(afterDbRefFetch);
- // ideally this would also gracefully run with callbacks
-
- dbRefFetcher.fetchDBRefs(true);
- }
- else
- {
- // call finished action directly
- afterDbRefFetch.finished();
- }
+ dbRefFetcher.fetchDBRefs(true);
}
-
+ else
+ {
+ // call finished action directly
+ afterDbRefFetch.finished();
+ }
+ return null;
};
- final Runnable revertview = new Runnable()
- {
- @Override
- public void run()
+ final Callable revertview = () -> {
+ if (lastSelected != null)
{
- if (lastSelected != null)
- {
- cmb_filterOption.setSelectedItem(lastSelected);
- }
- };
+ cmb_filterOption.setSelectedItem(lastSelected);
+ }
+ return null;
};
int threshold = Cache.getDefault("UNIPROT_AUTOFETCH_THRESHOLD",
THRESHOLD_WARN_UNIPROT_FETCH_NEEDED);
Console.debug("Using Uniprot fetch threshold of " + threshold);
if (ignoreGui || seqsWithoutSourceDBRef.size() < threshold)
{
- Executors.defaultThreadFactory().newThread(discoverCanonicalDBrefs)
- .start();
+ Executors.newSingleThreadExecutor().submit(discoverCanonicalDBrefs);
return;
}
// need cancel and no to result in the discoverPDB action - mocked is
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.Callable;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
MessageManager.getString("action.cancel") };
String title = MessageManager
.getString("label.adjust_foreground_text_colour_threshold");
- Runnable action = new Runnable() // response for 1 = Cancel
+ Callable<Void> action = () -> // response for 1 = Cancel
{
- @Override
- public void run()
- {
- restoreInitialSettings();
- }
+ restoreInitialSettings();
+ return null;
};
JvOptionPane.newOptionDialog(alignPanel.alignFrame)
.setResponseHandler(1, action).showInternalDialog(bigpanel,
*/
package jalview.gui;
-import java.util.Locale;
-
-import jalview.bin.Cache;
-import jalview.io.JalviewFileChooser;
-import jalview.io.JalviewFileView;
-import jalview.jbgui.GUserDefinedColours;
-import jalview.schemes.ColourSchemeI;
-import jalview.schemes.ColourSchemeLoader;
-import jalview.schemes.ColourSchemes;
-import jalview.schemes.ResidueProperties;
-import jalview.schemes.UserColourScheme;
-import jalview.util.ColorUtils;
-import jalview.util.Format;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-import jalview.xml.binding.jalview.JalviewUserColours;
-import jalview.xml.binding.jalview.JalviewUserColours.Colour;
-import jalview.xml.binding.jalview.ObjectFactory;
-
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
+import jalview.bin.Cache;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.jbgui.GUserDefinedColours;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeLoader;
+import jalview.schemes.ColourSchemes;
+import jalview.schemes.ResidueProperties;
+import jalview.schemes.UserColourScheme;
+import jalview.util.ColorUtils;
+import jalview.util.Format;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.xml.binding.jalview.JalviewUserColours;
+import jalview.xml.binding.jalview.JalviewUserColours.Colour;
+import jalview.xml.binding.jalview.ObjectFactory;
+
/**
* This panel allows the user to assign colours to Amino Acid residue codes, and
* save the colour scheme.
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);
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import jalview.bin.Cache;
import jalview.bin.Console;
private static final String oldTempFileSuffix = "_oldfile_tobedeleted";
+ // thread pool used for completablefutures
+ private static final ExecutorService executorService = Executors
+ .newFixedThreadPool(3);
+
private static List<BackupFiles> savesInProgress = new ArrayList<>();
+ private CompletableFuture<Boolean> myFuture = null;
+
private boolean addSaveInProgress()
{
if (savesInProgress.contains(this))
}
else
{
+ this.setMyFuture();
savesInProgress.add(this);
return true;
}
}
- private boolean removeSaveInProgress()
+ private boolean removeSaveInProgress(boolean ret)
{
if (savesInProgress.contains(this))
{
+ this.getMyFuture().complete(ret);
// remove all occurrences
while (savesInProgress.remove(this))
{
}
return true;
}
- else
+ return false;
+ }
+
+ private static CompletableFuture<Boolean> getNewFuture()
+ {
+ return new CompletableFuture<Boolean>()
{
- return false;
- }
+ };
+ }
+
+ private CompletableFuture<Boolean> getMyFuture()
+ {
+ return this.myFuture;
+ }
+
+ private void setMyFuture()
+ {
+ this.myFuture = getNewFuture();
}
public static boolean hasSavesInProgress()
return files;
}
+ public static List<CompletableFuture<Boolean>> savesInProgressCompletableFutures()
+ {
+ List<CompletableFuture<Boolean>> cfs = new ArrayList<>();
+ for (BackupFiles bfile : savesInProgress)
+ {
+ cfs.add(bfile.getMyFuture());
+ }
+ return cfs;
+ }
+
+ public static Future<Boolean> allSaved()
+ {
+ CompletableFuture<Boolean> f = new CompletableFuture<>();
+
+ executorService.submit(() -> {
+ for (BackupFiles buf : savesInProgress)
+ {
+ boolean allSaved = true;
+ try
+ {
+ allSaved &= buf.getMyFuture().get();
+ } catch (InterruptedException e)
+ {
+ Console.debug("InterruptedException waiting for files to save",
+ e);
+ } catch (ExecutionException e)
+ {
+ Console.debug("ExecutionException waiting for files to save", e);
+ }
+ f.complete(allSaved);
+ }
+ });
+ return f;
+ }
+
public BackupFiles(String filename)
{
this(new File(filename));
}
// remove this file from the save in progress stack
- removeSaveInProgress();
+ removeSaveInProgress(rename);
return rename;
}
*/
package jalview.io;
-import jalview.bin.Cache;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.LineartOptions;
-import jalview.gui.OOMWarning;
-import jalview.math.AlignmentDimension;
-import jalview.util.MessageManager;
-
import java.awt.Graphics;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import org.jfree.graphics2d.svg.SVGGraphics2D;
import org.jfree.graphics2d.svg.SVGHints;
+import jalview.bin.Cache;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.LineartOptions;
+import jalview.gui.OOMWarning;
+import jalview.math.AlignmentDimension;
+import jalview.util.MessageManager;
+
public class HtmlSvgOutput extends HTMLOutput
{
public HtmlSvgOutput(AlignmentPanel ap)
/*
* configure the action to run on OK in the dialog
*/
- Runnable okAction = new Runnable()
- {
- @Override
- public void run()
- {
- doOutput(textOption.get());
- }
+ Callable<Void> okAction = () -> {
+ doOutput(textOption.get());
+ return null;
};
/*
if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
{
LineartOptions svgOption = new LineartOptions("HTML", textOption);
- svgOption.setResponseAction(1, new Runnable()
- {
- @Override
- public void run()
- {
- setProgressMessage(MessageManager.formatMessage(
- "status.cancelled_image_export_operation",
- getDescription()));
- }
+ svgOption.setResponseAction(1, () -> {
+ setProgressMessage(MessageManager.formatMessage(
+ "status.cancelled_image_export_operation",
+ getDescription()));
+ return null;
});
svgOption.setResponseAction(0, okAction);
svgOption.showDialog();
//////////////////////////////////////////////////////////////////
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.JFileChooser;
import javax.swing.JList;
+import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SpringLayout;
import javax.swing.filechooser.FileFilter;
import javax.swing.plaf.basic.BasicFileChooserUI;
+import jalview.bin.Cache;
+import jalview.gui.JvOptionPane;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.util.dialogrunner.DialogRunnerI;
+
/**
* Enhanced file chooser dialog box.
*
{
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 DialogRunnerI setResponseHandler(Object response, Runnable action)
+ 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, 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();
+ }
}
}
import jalview.bin.Cache;
import jalview.gui.Desktop;
import jalview.io.FileFormatException;
-import jalview.jbgui.QuitHandler.QResponse;
import jalview.util.MessageManager;
import jalview.util.Platform;
@Override
public void actionPerformed(ActionEvent e)
{
- QResponse qresponse = Desktop.instance != null
- ? Desktop.instance.desktopQuit()
- : QResponse.QUIT;
- if (qresponse == QResponse.CANCEL_QUIT)
- {
- jalview.bin.Console
- .debug("GDesktop: Quit action cancelled by user");
- }
+ if (Desktop.instance != null)
+ Desktop.instance.desktopQuit();
}
});
aboutMenuItem.setText(MessageManager.getString("label.about"));
package jalview.jbgui;
import java.io.File;
-import java.util.Date;
import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import com.formdev.flatlaf.extras.FlatDesktop;
import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
import jalview.bin.Console;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
import jalview.io.BackupFiles;
import jalview.project.Jalview2XML;
import jalview.util.MessageManager;
public class QuitHandler
{
+ private static final int INITIAL_WAIT_FOR_SAVE = 3000;
+
+ private static final int NON_INTERACTIVE_WAIT_CYCLES = 2;
+
public static enum QResponse
{
- QUIT, CANCEL_QUIT, FORCE_QUIT
+ NULL, QUIT, CANCEL_QUIT, FORCE_QUIT
};
- public static void setQuitHandler()
+ private static ExecutorService executor = Executors.newFixedThreadPool(3);
+
+ public static QResponse setQuitHandler()
{
FlatDesktop.setQuitHandler(response -> {
- QResponse qresponse = getQuitResponse();
- switch (qresponse)
- {
- case QUIT:
+ Callable<QResponse> performQuit = () -> {
response.performQuit();
- break;
- case CANCEL_QUIT:
- response.cancelQuit();
- break;
- case FORCE_QUIT:
+ return setResponse(QResponse.QUIT);
+ };
+ Callable<QResponse> performForceQuit = () -> {
response.performQuit();
- break;
- default:
+ return setResponse(QResponse.FORCE_QUIT);
+ };
+ Callable<QResponse> cancelQuit = () -> {
response.cancelQuit();
- }
+ // reset
+ setResponse(QResponse.NULL);
+ // but return cancel
+ return QResponse.CANCEL_QUIT;
+ };
+ QResponse qresponse = getQuitResponse(true, performQuit,
+ performForceQuit, cancelQuit);
});
+
+ return gotQuitResponse();
}
- private static QResponse gotQuitResponse = QResponse.CANCEL_QUIT;
+ private static QResponse gotQuitResponse = QResponse.NULL;
- private static QResponse returnResponse(QResponse qresponse)
+ private static QResponse setResponse(QResponse qresponse)
{
gotQuitResponse = qresponse;
+ Console.debug("##### Setting gotQuitResponse to " + qresponse);
return qresponse;
}
return gotQuitResponse;
}
- public static QResponse getQuitResponse()
+ public static final Callable<QResponse> defaultCancelQuit = () -> {
+ Console.debug("QuitHandler: (default) Quit action CANCELLED by user");
+ // reset
+ setResponse(QResponse.NULL);
+ // and return cancel
+ return QResponse.CANCEL_QUIT;
+ };
+
+ public static final Callable<QResponse> defaultOkQuit = () -> {
+ Console.debug("QuitHandler: (default) Quit action CONFIRMED by user");
+ return setResponse(QResponse.QUIT);
+ };
+
+ public static final Callable<QResponse> defaultForceQuit = () -> {
+ Console.debug("QuitHandler: (default) Quit action FORCED by user");
+ // note that shutdown hook will not be run
+ Runtime.getRuntime().halt(0);
+ return setResponse(QResponse.FORCE_QUIT); // this line never reached!
+ };
+
+ public static QResponse getQuitResponse(boolean ui)
{
- return getQuitResponse(true);
+ return getQuitResponse(ui, defaultOkQuit, defaultForceQuit,
+ defaultCancelQuit);
}
- public static QResponse getQuitResponse(boolean ui)
+ private static boolean interactive = true;
+
+ public static QResponse getQuitResponse(boolean ui,
+ Callable<QResponse> okQuit, Callable<QResponse> forceQuit,
+ Callable<QResponse> cancelQuit)
{
- if (gotQuitResponse() != QResponse.CANCEL_QUIT)
+ QResponse got = gotQuitResponse();
+ if (got != QResponse.NULL && got != QResponse.CANCEL_QUIT)
{
- return returnResponse(getQuitResponse());
+ // quit has already been selected, continue with calling quit method
+ Console.debug("##### getQuitResponse called. gotQuitResponse=" + got);
+ return got;
}
- boolean interactive = ui && !Platform.isHeadless();
+ interactive = ui && !Platform.isHeadless();
// confirm quit if needed and wanted
boolean confirmQuit = true;
+ "' is/defaults to " + confirmQuit + " -- "
+ (confirmQuit ? "" : "not ") + "confirming quit");
}
+ got = confirmQuit ? QResponse.NULL : QResponse.QUIT;
+ Console.debug("initial calculation, got=" + got);
+ setResponse(got);
- int answer = JOptionPane.OK_OPTION;
-
- // if going to confirm, do it before the save in progress check to give
- // the save time to finish!
if (confirmQuit)
{
- answer = frameOnTop(
+
+ Console.debug("********************ABOUT TO CONFIRM QUIT");
+ JvOptionPane quitDialog = JvOptionPane.newOptionDialog()
+ .setResponseHandler(JOptionPane.YES_OPTION, defaultOkQuit)
+ .setResponseHandler(JOptionPane.NO_OPTION, defaultCancelQuit);
+ quitDialog.showDialogOnTopAsync(
new StringBuilder(
MessageManager.getString("label.quit_jalview"))
- .append(" ")
+ .append("\n")
.append(MessageManager
.getString("label.unsaved_changes"))
.toString(),
MessageManager.getString("action.quit"),
- JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+ JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
+ new Object[]
+ { MessageManager.getString("action.quit"),
+ MessageManager.getString("action.cancel") },
+ MessageManager.getString("action.quit"), true);
}
- if (answer == JOptionPane.CANCEL_OPTION)
+ got = gotQuitResponse();
+ Console.debug("first user response, got=" + got);
+ boolean wait = false;
+ if (got == QResponse.CANCEL_QUIT)
{
- Console.debug("QuitHandler: Quit action cancelled by user");
- return returnResponse(QResponse.CANCEL_QUIT);
+ // reset
+ setResponse(QResponse.NULL);
+ // but return cancel
+ return QResponse.CANCEL_QUIT;
+ }
+ else if (got == QResponse.QUIT)
+ {
+ if (Cache.getDefault("WAIT_FOR_SAVE", true)
+ && BackupFiles.hasSavesInProgress())
+ {
+ /*
+ Future<QResponse> waitGot = executor.submit(waitQuitCall);
+ try
+ {
+ got = waitGot.get();
+ } catch (InterruptedException | ExecutionException e)
+ {
+ jalview.bin.Console.debug(
+ "Exception during quit handling (wait for save)", e);
+ }
+ */
+ QResponse waitResponse = waitQuit(interactive, okQuit, forceQuit,
+ cancelQuit);
+ wait = waitResponse == QResponse.QUIT;
+ }
}
- // check for saves in progress
- int waitForSave = 1000; // MAKE THIS BETTER
- AlignFrame[] afArray = Desktop.getAlignFrames();
- if (afArray == null || afArray.length == 0)
+ Callable<QResponse> next = null;
+ switch (gotQuitResponse())
{
- // no change
+ case QUIT:
+ Console.debug("### User selected QUIT");
+ next = okQuit;
+ break;
+ case FORCE_QUIT: // not actually an option at this stage
+ Console.debug("### User selected FORCE QUIT");
+ next = forceQuit;
+ break;
+ default:
+ Console.debug("### User selected CANCEL QUIT");
+ next = cancelQuit;
+ break;
}
- else
+ try
+ {
+ got = executor.submit(next).get();
+ } catch (InterruptedException | ExecutionException e)
+ {
+ jalview.bin.Console
+ .debug("Exception during quit handling (final choice)", e);
+ }
+ jalview.bin.Console.debug("### nextResponse=" + got.toString());
+ setResponse(got);
+
+ return gotQuitResponse();
+ }
+
+ private static QResponse waitQuit(boolean interactive,
+ Callable<QResponse> okQuit, Callable<QResponse> forceQuit,
+ Callable<QResponse> cancelQuit)
+ {
+ jalview.bin.Console.debug("#### waitQuit started");
+ // check for saves in progress
+ if (!BackupFiles.hasSavesInProgress())
+ return QResponse.QUIT;
+
+ int waitTime = INITIAL_WAIT_FOR_SAVE; // start with 3 second wait
+ AlignFrame[] afArray = Desktop.getAlignFrames();
+ if (!(afArray == null || afArray.length == 0))
{
int size = 0;
for (int i = 0; i < afArray.length; i++)
{
AlignFrame af = afArray[i];
- List<AlignmentViewPanel> avpList = (List<AlignmentViewPanel>) af
- .getAlignPanels();
+ List<? extends AlignmentViewPanel> avpList = af.getAlignPanels();
for (AlignmentViewPanel avp : avpList)
{
AlignmentI a = avp.getAlignment();
}
}
}
- waitForSave = size;
- Console.debug("Set waitForSave to " + waitForSave);
+ waitTime = Math.max(waitTime, size / 2);
+ Console.debug("Set waitForSave to " + waitTime);
}
- int waitIncrement = 3000;
- long startTime = new Date().getTime();
- boolean saving = BackupFiles.hasSavesInProgress();
- if (saving)
+
+ // future that returns a Boolean when all files are saved
+ CompletableFuture<Boolean> filesAllSaved = new CompletableFuture<>();
+
+ // callback as each file finishes saving
+ for (CompletableFuture<Boolean> cf : BackupFiles
+ .savesInProgressCompletableFutures())
+ {
+ // if this is the last one then complete filesAllSaved
+ cf.whenComplete((ret, e) -> {
+ if (!BackupFiles.hasSavesInProgress())
+ {
+ filesAllSaved.complete(true);
+ }
+ });
+ }
+
+ final int waitTimeFinal = waitTime;
+ // timeout the wait -- will result in another wait button when looped
+ CompletableFuture<Boolean> waitTimeout = CompletableFuture
+ .supplyAsync(() -> {
+ executor.submit(() -> {
+ try
+ {
+ Thread.sleep(waitTimeFinal);
+ } catch (InterruptedException e)
+ {
+ // probably interrupted by all files saving
+ }
+ });
+ return true;
+ });
+ CompletableFuture<Object> waitForSave = CompletableFuture
+ .anyOf(waitTimeout, filesAllSaved);
+ Console.debug("##### WAITFORSAVE RUNNING");
+
+ QResponse waitResponse = QResponse.NULL;
+
+ int iteration = 0;
+ boolean doIterations = true;
+ while (doIterations && BackupFiles.hasSavesInProgress()
+ && iteration++ < (interactive ? 100 : 5))
{
- boolean waiting = (new Date().getTime() - startTime) < waitForSave;
- while (saving && waiting)
+ try
{
- saving = !waitForSave(waitIncrement);
- waiting = (new Date().getTime() - startTime) < waitForSave;
+ waitForSave.get();
+ } catch (InterruptedException | ExecutionException e1)
+ {
+ Console.debug(
+ "Exception whilst waiting for files to save before quitting",
+ e1);
}
-
- if (saving) // still saving after a wait
+ if (interactive)
{
- StringBuilder messageSB = new StringBuilder(
- MessageManager.getString("label.save_in_progress"));
- messageSB.append(":");
- boolean any = false;
- for (File file : BackupFiles.savesInProgressFiles())
+ Console.debug("********************About to make waitDialog");
+ JvOptionPane waitDialog = JvOptionPane.newOptionDialog()
+ .setResponseHandler(JOptionPane.YES_OPTION, defaultOkQuit)
+ .setResponseHandler(JOptionPane.NO_OPTION, forceQuit)
+ .setResponseHandler(JOptionPane.CANCEL_OPTION, cancelQuit);
+
+ // callback as each file finishes saving
+ for (CompletableFuture<Boolean> cf : BackupFiles
+ .savesInProgressCompletableFutures())
{
- messageSB.append("\n- ");
- messageSB.append(file.getName());
- any = true;
+ // update the list of saving files as they save too
+ cf.thenRun(() -> {
+ waitDialog.setMessage(waitingForSaveMessage());
+ });
+ // if this is the last one then close the dialog
+ cf.whenComplete((ret, e) -> {
+ if (!BackupFiles.hasSavesInProgress())
+ {
+ // like a click on Wait button
+ Console.debug(
+ "***** TRYING TO MAKE THE WAIT FOR SAVE DIALOG DISAPPEAR!");
+ waitDialog.setValue(JOptionPane.YES_OPTION);
+ }
+ });
}
- if (!any)
- {
- messageSB.append("\n");
- messageSB.append(MessageManager.getString("label.unknown"));
- }
- int waitLonger = interactive ? JOptionPane.YES_OPTION
- : JOptionPane.NO_OPTION;
- while (saving && waitLonger == JOptionPane.YES_OPTION)
+
+ waitDialog.showDialogOnTopAsync(waitingForSaveMessage(),
+ MessageManager.getString("action.wait"),
+ JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.WARNING_MESSAGE, null, new Object[]
+ { MessageManager.getString("action.wait"),
+ MessageManager.getString("action.force_quit"),
+ MessageManager.getString("action.cancel_quit") },
+ MessageManager.getString("action.wait"), true);
+ Console.debug("********************Finished waitDialog");
+
+ waitResponse = gotQuitResponse();
+ Console.debug("####### WAITFORSAVE SET: " + waitResponse);
+ switch (waitResponse)
{
- waitLonger = waitForceQuitCancelQuitOptionDialog(
- messageSB.toString(),
- MessageManager.getString("action.wait"));
- if (waitLonger == JOptionPane.YES_OPTION) // wait
- {
- // do wait stuff
- saving = !waitForSave(waitIncrement);
- }
- else if (waitLonger == JOptionPane.NO_OPTION) // force quit
- {
- // do a force quit
- return returnResponse(QResponse.FORCE_QUIT); // shouldn't reach this
- }
- else if (waitLonger == JOptionPane.CANCEL_OPTION) // cancel quit
- {
- return returnResponse(QResponse.CANCEL_QUIT);
- }
- else
- {
- Console.debug("**** Shouldn't have got here!");
- }
+ case QUIT: // wait -- do another iteration
+ break;
+ case FORCE_QUIT:
+ doIterations = false;
+ break;
+ case CANCEL_QUIT:
+ doIterations = false;
+ break;
+ case NULL: // already cancelled
+ doIterations = false;
+ break;
+ default:
}
- }
- }
+ } // end if interactive
- // not cancelled and not saving
- return returnResponse(QResponse.QUIT);
- }
+ }
+ waitResponse = gotQuitResponse();
- public static int frameOnTop(String label, String actionString,
- int JOPTIONPANE_OPTION, int JOPTIONPANE_MESSAGETYPE)
- {
- return frameOnTop(new JFrame(), label, actionString, JOPTIONPANE_OPTION,
- JOPTIONPANE_MESSAGETYPE);
- }
+ Console.debug("####### WAITFORSAVE RETURNING: " + waitResponse);
+ return waitResponse;
+ };
- public static int frameOnTop(JFrame dialogParent, String label,
- String actionString, int JOPTIONPANE_OPTION,
- int JOPTIONPANE_MESSAGETYPE)
+ public static void okk()
{
- // ensure Jalview window is brought to front 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 instead
-
- dialogParent.setAlwaysOnTop(true);
-
- int answer = JOptionPane.showConfirmDialog(dialogParent, label,
- actionString, JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE);
-
- dialogParent.setAlwaysOnTop(false);
- dialogParent.dispose();
-
- return answer;
- }
+ /*
+ if (false)
+ {
+ if (false)
+ {
+
+ waitLonger = JOptionPane.showOptionDialog(dialogParent,
+ waitingForSaveMessage(),
+ MessageManager.getString("action.wait"),
+ JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.WARNING_MESSAGE, null, options, wait);
+ }
+ else
+ {
+ // non-interactive
+ waitLonger = iteration < NON_INTERACTIVE_WAIT_CYCLES
+ ? JOptionPane.YES_OPTION
+ : JOptionPane.NO_OPTION;
+ }
+
+ if (waitLonger == JOptionPane.YES_OPTION) // "wait"
+ {
+ saving = !waitForSave(waitIncrement);
+ }
+ else if (waitLonger == JOptionPane.NO_OPTION) // "force
+ // quit"
+ {
+ // do a force quit
+ return setResponse(QResponse.FORCE_QUIT);
+ }
+ else if (waitLonger == JOptionPane.CANCEL_OPTION) // cancel quit
+ {
+ return setResponse(QResponse.CANCEL_QUIT);
+ }
+ else
+ {
+ // Most likely got here by user dismissing the dialog with the
+ // 'x'
+ // -- treat as a "Cancel"
+ return setResponse(QResponse.CANCEL_QUIT);
+ }
+ }
+
+ // not sure how we got here, best be safe
+ return QResponse.CANCEL_QUIT;
+ */
+ };
private static int waitForceQuitCancelQuitOptionDialog(Object message,
String title)
MessageManager.getString("action.force_quit"),
MessageManager.getString("action.cancel_quit") };
+ // BackupFiles.setWaitForSaveDialog(dialogParent);
+
int answer = JOptionPane.showOptionDialog(dialogParent, message, title,
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE,
null, options, wait);
+ // BackupFiles.clearWaitForSaveDialog();
+
return answer;
}
- private static boolean waitForSave(long t)
+ private static String waitingForSaveMessage()
+ {
+ StringBuilder messageSB = new StringBuilder(
+ MessageManager.getString("label.save_in_progress"));
+ boolean any = false;
+ for (File file : BackupFiles.savesInProgressFiles())
+ {
+ messageSB.append("\n- ");
+ messageSB.append(file.getName());
+ any = true;
+ }
+ if (!any)
+ {
+ messageSB.append("\n");
+ messageSB.append(MessageManager.getString("label.unknown"));
+ }
+
+ return messageSB.toString();
+ }
+
+ private static Boolean waitForSave(long t)
{
boolean ret = false;
try
*/
package jalview.util.dialogrunner;
+import java.util.concurrent.Callable;
+
/**
* An interface for blocking dialog response handling. This is motivated by
* JalviewJS - when running as Javascript, there is only a single thread, and
* @param action
* @return
*/
- DialogRunnerI setResponseHandler(Object response, Runnable action);
+ DialogRunnerI setResponseHandler(Object response, Callable action);
+
+ // DialogRunnerI setResponseHandler(Object response, Runnable action);
/**
* Runs the registered handler (if any) for the given response. The default