From df97c670f60a8dc0082b464ec542c43d0b6f16fd Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Mon, 12 Aug 2024 20:47:33 +0100 Subject: [PATCH] JAL-4442 Add a wait for termination of button action handlers method --- src/jalview/gui/JvOptionPane.java | 45 +++++++++++++++++++++------- src/jalview/gui/QuitHandler.java | 59 +++++++++++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 19 deletions(-) diff --git a/src/jalview/gui/JvOptionPane.java b/src/jalview/gui/JvOptionPane.java index 7a5daf7..726e942 100644 --- a/src/jalview/gui/JvOptionPane.java +++ b/src/jalview/gui/JvOptionPane.java @@ -1,14 +1,14 @@ /* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors - * + * * This file is part of Jalview. - * + * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. - * + * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR @@ -45,6 +45,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import javax.swing.Icon; import javax.swing.JButton; @@ -784,7 +785,7 @@ public class JvOptionPane extends JOptionPane /** * create a new option dialog that can be used to register responses - along * lines of showOptionDialog - * + * * @param desktop * @param question * @param string @@ -985,10 +986,11 @@ public class JvOptionPane extends JOptionPane if (!Platform.isJS()) /** * Java only - * + * * @j2sIgnore */ { + Console.debug("Handling response for " + response); handleResponse(response); } } @@ -1198,7 +1200,7 @@ public class JvOptionPane extends JOptionPane if (!Platform.isJS()) /** * Java only - * + * * @j2sIgnore */ { @@ -1209,7 +1211,7 @@ public class JvOptionPane extends JOptionPane /* * @Override public JvOptionPane setResponseHandler(Object response, Runnable * action) { callbacks.put(response, new Callable() { - * + * * @Override public Void call() { action.run(); return null; } }); return this; * } */ @@ -1355,7 +1357,7 @@ public class JvOptionPane extends JOptionPane * 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. - * + * * @param evt */ @Override @@ -1389,7 +1391,8 @@ public class JvOptionPane extends JOptionPane { try { - new Thread(action).start(); + executor.submit(action); + // new Thread(action).start(); // action.call(); } catch (Exception e) { @@ -1542,7 +1545,7 @@ public class JvOptionPane extends JOptionPane /** * 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) @@ -1751,4 +1754,26 @@ public class JvOptionPane extends JOptionPane } } + private static final long defaultTimeout = 500; + + public boolean waitForHandlerToFinish() + { + return waitForHandlerToFinish(defaultTimeout); + } + + public boolean waitForHandlerToFinish(long timeout) + { + if (executor != null) + { + try + { + return executor.awaitTermination(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) + { + Console.debug("Action was interrupted", e); + } + } + return true; + } + } diff --git a/src/jalview/gui/QuitHandler.java b/src/jalview/gui/QuitHandler.java index 1b48c6d..9917222 100644 --- a/src/jalview/gui/QuitHandler.java +++ b/src/jalview/gui/QuitHandler.java @@ -1,14 +1,14 @@ /* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors - * + * * This file is part of Jalview. - * + * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. - * + * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR @@ -95,10 +95,12 @@ public class QuitHandler protected static QResponse setResponse(QResponse qresponse) { + Console.debug("setResponse(" + qresponse.toString() + ")"); gotQuitResponse = qresponse; if ((qresponse == QResponse.CANCEL_QUIT || qresponse == QResponse.NULL) && flatlafResponse != null) { + Console.debug("Running flatLafResponse.cancelQuit()"); flatlafResponse.cancelQuit(); } return qresponse; @@ -137,9 +139,13 @@ public class QuitHandler Runnable forceQuit, Runnable cancelQuit) { QResponse got = gotQuitResponse(); + Console.debug("Quit response is '" + got.toString() + + "' at start of getQuitResponse(...)"); if (got != QResponse.NULL && got != QResponse.CANCEL_QUIT) { // quit has already been selected, continue with calling quit method + Console.debug("Returning already set quit response of '" + + got.toString() + "' at start of getQuitResponse(...)"); return got; } @@ -162,13 +168,17 @@ public class QuitHandler confirmQuit = jalview.bin.Cache .getDefault(jalview.gui.Desktop.CONFIRM_KEYBOARD_QUIT, true); Console.debug("Jalview property '" - + jalview.gui.Desktop.CONFIRM_KEYBOARD_QUIT - + "' is/defaults to " + confirmQuit + " -- " - + (confirmQuit ? "" : "not ") + "confirming quit"); + + jalview.gui.Desktop.CONFIRM_KEYBOARD_QUIT + "' is " + + confirmQuit + " -- " + (confirmQuit ? "" : "not ") + + "confirming quit"); } + got = confirmQuit ? QResponse.NULL : QResponse.QUIT; setResponse(got); + Console.debug("confirmQuit is '" + confirmQuit + + "', setting quit response to " + got); + if (confirmQuit) { String messageString = MessageManager @@ -182,17 +192,21 @@ public class QuitHandler qd.showDialogOnTopAsync( new StringBuilder( MessageManager.getString("label.quit_jalview")) - .append("\n").append(messageString) - .toString(), + .append("\n").append(messageString).toString(), MessageManager.getString("action.quit"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] { MessageManager.getString("action.quit"), MessageManager.getString("action.cancel") }, MessageManager.getString("action.quit"), true); + + Console.debug("Waiting for response handler to run action"); + qd.waitForHandlerToFinish(); } got = gotQuitResponse(); + Console.debug("Quit response is '" + got.toString() + + "' after response handler"); // check for external viewer frames if (got != QResponse.CANCEL_QUIT) @@ -246,6 +260,9 @@ public class QuitHandler got = gotQuitResponse(); + Console.debug("Quit response is '" + got.toString() + + "' after external structure viewer check"); + boolean wait = false; if (got == QResponse.CANCEL_QUIT) { @@ -257,6 +274,8 @@ public class QuitHandler } else if (got == QResponse.QUIT) { + Console.debug("Quit response is '" + got.toString() + + "' before waiting for save"); if (Cache.getDefault("WAIT_FOR_SAVE", true) && BackupFiles.hasSavesInProgress()) { @@ -264,25 +283,40 @@ public class QuitHandler QResponse waitResponse = gotQuitResponse(); wait = waitResponse == QResponse.QUIT; } + Console.debug("Quit response is '" + got.toString() + + "' after waiting for save"); } Runnable next = null; + String nextName = null; + got = gotQuitResponse(); + Console.debug("Quit response is '" + got.toString() + + "' before setting next"); switch (gotQuitResponse()) { case QUIT: next = okQuit; + nextName = "okQuit"; break; case FORCE_QUIT: // not actually an option at this stage next = forceQuit; + nextName = "forceQuit"; break; default: next = cancelQuit; + nextName = "cancelQuit"; break; } + Console.debug( + "Quit response is '" + got.toString() + "' after setting next"); + Console.debug("Next is '" + next + "'"); try { executor.submit(next).get(); + Console.debug(next + " is submitted"); got = gotQuitResponse(); + Console.debug("Quit response is '" + got.toString() + + "' after submitting next"); } catch (RejectedExecutionException e) { // QuitHander.abortQuit() probably called @@ -295,16 +329,23 @@ public class QuitHandler jalview.bin.Console .debug("Exception during quit handling (final choice)", e); } + Console.debug("Setting response to '" + got.toString() + + "' after submitting next"); setResponse(got); + Console.debug("Checking if quit was cancelled"); if (quitCancelled()) { // reset if cancelled Console.debug("Quit cancelled"); setResponse(QResponse.NULL); + Console.debug("Set response to " + QResponse.NULL.toString() + + ". Returning " + QResponse.CANCEL_QUIT); return QResponse.CANCEL_QUIT; } - return gotQuitResponse(); + got = gotQuitResponse(); + Console.debug("Returning " + got.toString()); + return got; } private static QResponse waitQuit(boolean interactive, Runnable okQuit, -- 1.7.10.2