From 1213d49ca3df8f48360da857121805d088c13aab Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Wed, 11 Oct 2023 17:55:09 +0100 Subject: [PATCH 1/1] JAL-629 Add a timeout to modal dialogs for command line warning --- src/jalview/bin/Jalview.java | 10 ++++---- src/jalview/gui/Desktop.java | 18 +++++++++++---- src/jalview/gui/JvOptionPane.java | 46 ++++++++++++++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 18e73ed..ba418fe 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -2038,8 +2038,8 @@ public class Jalview j.getArgParser().getMixedExamples()); String quit = MessageManager.getString("action.quit"); - Desktop.instance.nonBlockingDialog(title, warning, quit, - JvOptionPane.WARNING_MESSAGE, false, true); + Desktop.instance.nonBlockingDialog(title, warning, null, quit, + JvOptionPane.WARNING_MESSAGE, false, false, true, 30000); Jalview.exit( "Exiting due to mixed old and new command line arguments.", @@ -2063,8 +2063,8 @@ public class Jalview { String cont = MessageManager.getString("label.continue"); - Desktop.instance.nonBlockingDialog(32, 2, title, warning, url, cont, - JvOptionPane.WARNING_MESSAGE, false, true, true); + Desktop.instance.nonBlockingDialog(title, warning, url, cont, + JvOptionPane.WARNING_MESSAGE, false, true, true, 2000); } } if (j.getCommands() != null && j.getCommands().getErrors().size() > 0) @@ -2084,7 +2084,7 @@ public class Jalview Math.max(message.length(), Math.min(60, shortest)), Math.min(errors.size(), 20), title, message, j.getCommands().errorsToString(), ok, - JvOptionPane.WARNING_MESSAGE, true, false, true); + JvOptionPane.WARNING_MESSAGE, true, false, true, -1); } } } diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index e0e2307..d5840e6 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -3762,13 +3762,21 @@ public class Desktop extends jalview.jbgui.GDesktop public void nonBlockingDialog(String title, String message, String button, int type, boolean scrollable, boolean modal) { - nonBlockingDialog(32, 2, title, message, null, button, type, scrollable, - false, modal); + nonBlockingDialog(title, message, null, button, type, scrollable, false, + modal, -1); + } + + public void nonBlockingDialog(String title, String message, + String boxtext, String button, int type, boolean scrollable, + boolean html, boolean modal, int timeout) + { + nonBlockingDialog(32, 2, title, message, boxtext, button, type, + scrollable, false, modal, timeout); } public void nonBlockingDialog(int width, int height, String title, String message, String boxtext, String button, int type, - boolean scrollable, boolean html, boolean modal) + boolean scrollable, boolean html, boolean modal, int timeout) { if (type < 0) { @@ -3830,9 +3838,11 @@ public class Desktop extends jalview.jbgui.GDesktop jvp.setResponseHandler(JOptionPane.YES_OPTION, () -> { }); + jvp.setTimeout(timeout); + JButton jb = new JButton(button); jvp.showDialogOnTopAsync(this, jp, title, JOptionPane.YES_OPTION, type, null, new Object[] - { button }, button, modal, null, false); + { button }, button, modal, new JButton[] { jb }, false); } } diff --git a/src/jalview/gui/JvOptionPane.java b/src/jalview/gui/JvOptionPane.java index 3f5de0a..0a7c49e 100644 --- a/src/jalview/gui/JvOptionPane.java +++ b/src/jalview/gui/JvOptionPane.java @@ -88,6 +88,13 @@ public class JvOptionPane extends JOptionPane private Map callbacks = new HashMap<>(); + private int timeout = -1; + + public void setTimeout(int i) + { + timeout = i; + } + /* * JalviewJS reports user choice in the dialog as the selected option (text); * this list allows conversion to index (int) @@ -851,6 +858,38 @@ public class JvOptionPane extends JOptionPane "Supplied buttons array not the same length as supplied options array."); break NOTNULL; } + + // run through buttons for initialValue first so can set a final + // timeoutThreadF + Thread timeoutThread = null; + for (int i = 0; i < options.length; i++) + { + Object o = options[i]; + JButton jb = buttons[i]; + if (o.equals(initialValue)) + { + initialValueButton = jb; + if (timeout > 0 && initialValueButton != null + && initialValueButton instanceof JButton) + { + Runnable timeoutClose = () -> { + try + { + Thread.sleep(timeout); + } catch (InterruptedException e) + { + Console.debug( + "Dialog timeout interrupted. Probably a button pressed."); + } + jb.doClick(); + }; + timeoutThread = new Thread(timeoutClose); + } + } + } + final Thread timeoutThreadF = timeoutThread; + timeoutThreadF.start(); + int[] buttonActions = { JOptionPane.YES_OPTION, JOptionPane.NO_OPTION, JOptionPane.CANCEL_OPTION }; for (int i = 0; i < options.length; i++) @@ -860,9 +899,6 @@ public class JvOptionPane extends JOptionPane "Setting button " + i + " to '" + o.toString() + "'"); JButton jb = buttons[i]; - if (o.equals(initialValue)) - initialValueButton = jb; - int buttonAction = buttonActions[i]; Runnable action = callbacks.get(buttonAction); jb.setText((String) o); @@ -871,6 +907,10 @@ public class JvOptionPane extends JOptionPane @Override public void actionPerformed(ActionEvent e) { + if (timeoutThreadF != null) + { + timeoutThreadF.interrupt(); + } Object obj = e.getSource(); if (obj == null || !(obj instanceof Component)) -- 1.7.10.2