diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java index 3cffeceb42..95f972327e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java @@ -17,14 +17,10 @@ package ghidra.app.script; import java.awt.Color; import java.io.*; -import java.lang.reflect.InvocationTargetException; import java.rmi.ConnectException; import java.util.*; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicBoolean; -import javax.swing.SwingUtilities; - -import docking.DockingWindowManager; import docking.widgets.OptionDialog; import docking.widgets.dialogs.MultiLineMessageDialog; import docking.widgets.filechooser.GhidraFileChooser; @@ -87,12 +83,12 @@ import ghidra.util.task.TaskMonitor; * When you create a new script using the script manager, * you will automatically receive a source code stub (as shown below). *
- *  //TODO write a description for this script
+ *  // TODO write a description for this script
  *
  * 	public class NewScript extends GhidraScript {
  *
  * 		public void run() throws Exception {
- * 			//TODO Add User Code Here
+ * 			// TODO Add User Code Here
  * 		}
  * 	}
  * 
@@ -565,7 +561,7 @@ public abstract class GhidraScript extends FlatProgramAPI { // only change client authenticator in headless mode try { HeadlessClientAuthenticator - .installHeadlessClientAuthenticator(ClientUtil.getUserName(), null, false); + .installHeadlessClientAuthenticator(ClientUtil.getUserName(), null, false); } catch (IOException e) { throw new RuntimeException("Unexpected Exception", e); @@ -1340,10 +1336,9 @@ public abstract class GhidraScript extends FlatProgramAPI { Msg.error(this, errorBuffer.toString()); } else { - MultiLineMessageDialog dialog = new MultiLineMessageDialog("Analysis Options", + MultiLineMessageDialog.showMessageDialog(null, "Analysis Options", "Ghidra encountered error(s) when attempting to set analysis options.", - errorBuffer.toString(), MultiLineMessageDialog.WARNING_MESSAGE, false); - DockingWindowManager.showDialog(null, dialog); + errorBuffer.toString(), MultiLineMessageDialog.WARNING_MESSAGE); } } } @@ -1366,10 +1361,9 @@ public abstract class GhidraScript extends FlatProgramAPI { Msg.error(this, errorMsg); } else { - MultiLineMessageDialog dialog = new MultiLineMessageDialog("Analysis Options", + MultiLineMessageDialog.showMessageDialog(null, "Analysis Options", "Ghidra encountered error(s) when attempting to set analysis options.", - errorMsg, MultiLineMessageDialog.WARNING_MESSAGE, false); - DockingWindowManager.showDialog(null, dialog); + errorMsg, MultiLineMessageDialog.WARNING_MESSAGE); } } } @@ -1796,23 +1790,8 @@ public abstract class GhidraScript extends FlatProgramAPI { Msg.info(this, message); } else { - - final String name = getClass().getName(); - if (SwingUtilities.isEventDispatchThread()) { - Msg.showInfo(getClass(), null, name, message); - } - else { - try { - SwingUtilities - .invokeAndWait(() -> Msg.showInfo(getClass(), null, name, message)); - } - catch (InterruptedException e) { - // shouldn't happen - } - catch (InvocationTargetException e) { - // shouldn't happen - } - } + String name = getClass().getName(); + Msg.showInfo(getClass(), null, name, message); } } @@ -1981,7 +1960,7 @@ public abstract class GhidraScript extends FlatProgramAPI { T lastValue = (mappedValue != null) ? mappedValue : defaultValue; - T newValue = asker.apply(lastValue); // may be cancelled + T newValue = swing(asker, lastValue); // may be cancelled map.put(clazz, newValue); return newValue; @@ -2039,22 +2018,17 @@ public abstract class GhidraScript extends FlatProgramAPI { File choice = doAsk(File.class, title, approveButtonText, existingValue, lastValue -> { GhidraFileChooser chooser = new GhidraFileChooser(null); - AtomicReference ref = new AtomicReference<>(); - - Runnable r = () -> { - chooser.setSelectedFile(lastValue); - chooser.setTitle(title); - chooser.setApproveButtonText(approveButtonText); - chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY); - ref.set(chooser.getSelectedFile()); - }; - Swing.runNow(r); + chooser.setSelectedFile(lastValue); + chooser.setTitle(title); + chooser.setApproveButtonText(approveButtonText); + chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY); + File file = chooser.getSelectedFile(); if (chooser.wasCancelled()) { throw new CancelledException(); } - return ref.get(); + return file; }); return choice; @@ -2121,22 +2095,17 @@ public abstract class GhidraScript extends FlatProgramAPI { File choice = doAsk(DIRECTORY.class, title, approveButtonText, existingValue, lastValue -> { GhidraFileChooser chooser = new GhidraFileChooser(null); - AtomicReference ref = new AtomicReference<>(); - - Runnable r = () -> { - chooser.setSelectedFile(lastValue); - chooser.setTitle(title); - chooser.setApproveButtonText(approveButtonText); - chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY); - ref.set(chooser.getSelectedFile()); - }; - Swing.runNow(r); + chooser.setSelectedFile(lastValue); + chooser.setTitle(title); + chooser.setApproveButtonText(approveButtonText); + chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY); + File file = chooser.getSelectedFile(); if (chooser.wasCancelled()) { throw new CancelledException(); } - return ref.get(); + return file; }); return choice; @@ -2230,19 +2199,13 @@ public abstract class GhidraScript extends FlatProgramAPI { doAsk(clazz, title, approveButtonText, existingValue, lastValue -> { SelectLanguageDialog dialog = new SelectLanguageDialog(title, approveButtonText); - AtomicReference ref = new AtomicReference<>(); - - Runnable r = () -> { - dialog.setSelectedLanguage(lastValue); - ref.set(dialog.getSelectedLanguage()); - }; - Swing.runNow(r); - + dialog.setSelectedLanguage(lastValue); + dialog.show(); if (dialog.wasCancelled()) { throw new CancelledException(); } - return ref.get(); + return dialog.getSelectedLanguage(); }); return choice; @@ -2309,21 +2272,12 @@ public abstract class GhidraScript extends FlatProgramAPI { DomainFolder choice = doAsk(Program.class, title, "", existingValue, lastValue -> { DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.CHOOSE_FOLDER); - AtomicReference ref = new AtomicReference<>(); - - dtd.addOkActionListener(e -> { - ref.set(dtd.getDomainFolder()); - dtd.close(); - }); - - Runnable r = () -> dtd.showComponent(); - Swing.runNow(r); - + dtd.show(); if (dtd.wasCancelled()) { throw new CancelledException(); } - return ref.get(); + return dtd.getDomainFolder(); }); return choice; @@ -2676,21 +2630,12 @@ public abstract class GhidraScript extends FlatProgramAPI { DomainFile choice = doAsk(Program.class, title, "", existingValue, lastValue -> { DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.OPEN); - AtomicReference ref = new AtomicReference<>(); - - dtd.addOkActionListener(e -> { - ref.set(dtd.getDomainFile()); - dtd.close(); - }); - - Runnable r = () -> dtd.showComponent(); - Swing.runNow(r); - + dtd.show(); if (dtd.wasCancelled()) { throw new CancelledException(); } - return ref.get(); + return dtd.getDomainFile(); }); if (choice == null) { @@ -2768,21 +2713,12 @@ public abstract class GhidraScript extends FlatProgramAPI { DomainFile choice = doAsk(DomainFile.class, title, message, existingValue, lastValue -> { DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.OPEN); - AtomicReference ref = new AtomicReference<>(); - - dtd.addOkActionListener(e -> { - ref.set(dtd.getDomainFile()); - dtd.close(); - }); - - Runnable r = () -> dtd.showComponent(); - Swing.runNow(r); - + dtd.show(); if (dtd.wasCancelled()) { throw new CancelledException(); } - return ref.get(); + return dtd.getDomainFile(); }); return choice; @@ -3170,18 +3106,14 @@ public abstract class GhidraScript extends FlatProgramAPI { Class clazz = choices.get(0).getClass(); List choice = doAsk(clazz, title, message, existingValue, lastValue -> { - AtomicReference> reference = new AtomicReference<>(); MultipleOptionsDialog dialog = new MultipleOptionsDialog<>(title, message, choices, true); - - Runnable r = () -> reference.set(dialog.getUserChoices()); - Swing.runNow(r); - + dialog.show(); if (dialog.isCanceled()) { throw new CancelledException(); } - return reference.get(); + return dialog.getUserChoices(); }); return choice; @@ -3247,18 +3179,14 @@ public abstract class GhidraScript extends FlatProgramAPI { Class clazz = choices.get(0).getClass(); List choice = doAsk(clazz, title, message, existingValue, lastValue -> { - AtomicReference> reference = new AtomicReference<>(); MultipleOptionsDialog dialog = new MultipleOptionsDialog<>(title, message, choices, choiceLabels, true); - - Runnable r = () -> reference.set(dialog.getUserChoices()); - Swing.runNow(r); - + dialog.show(); if (dialog.isCanceled()) { throw new CancelledException(); } - return reference.get(); + return dialog.getUserChoices(); }); return choice; @@ -3742,22 +3670,20 @@ public abstract class GhidraScript extends FlatProgramAPI { Swing.runLater(runnable); } - private void show(final String title, final TableService table, - final AddressSetView addresses) { + private void show(String title, TableService table, AddressSetView addresses) { PluginTool tool = state.getTool(); if (tool == null) { println("Couldn't show table!"); return; } - Runnable runnable = () -> { + Swing.runLater(() -> { AddressSetTableModel model = new AddressSetTableModel(title, state.getTool(), currentProgram, addresses, null); TableComponentProvider
tableProvider = table.showTableWithMarkers(title, "GhidraScript", model, Color.GREEN, null, "Script Results", null); tableProvider.installRemoveItemsAction(); - }; - Swing.runLater(runnable); + }); } private Map, Object> getScriptMap(String title, String message) { @@ -3780,4 +3706,26 @@ public abstract class GhidraScript extends FlatProgramAPI { } return buffer.toString(); } + + private static T swing(CancellableFunction f, T t) throws CancelledException { + + AtomicBoolean wasCancelled = new AtomicBoolean(); + T result = Swing.runNow(() -> { + + try { + return f.apply(t); + } + catch (CancelledException e) { + wasCancelled.set(true); + return null; + } + }); + + if (wasCancelled.get()) { + throw new CancelledException(); + } + + return result; + } + } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/MultipleOptionsDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/MultipleOptionsDialog.java index 83438fa00f..b0b388ca07 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/MultipleOptionsDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/MultipleOptionsDialog.java @@ -28,7 +28,6 @@ import docking.DialogComponentProvider; import docking.DockingWindowManager; import docking.widgets.checkbox.GCheckBox; import docking.widgets.label.GLabel; -import ghidra.util.Msg; public class MultipleOptionsDialog extends DialogComponentProvider { @@ -104,21 +103,10 @@ public class MultipleOptionsDialog extends DialogComponentProvider { addWorkPanel(panel); addOKButton(); addCancelButton(); + } - if (SwingUtilities.isEventDispatchThread()) { - DockingWindowManager.showDialog(null, this); - } - else { - try { - SwingUtilities.invokeAndWait( - () -> DockingWindowManager.showDialog(null, MultipleOptionsDialog.this)); - } - catch (Exception e) { - Msg.error(this, "Unable to get choices from the user; error showing dialog - " + - e.getMessage()); - } - } - + public void show() { + DockingWindowManager.showDialog(null, this); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/SelectLanguageDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/SelectLanguageDialog.java index 6e8ba4e7ec..499abdb4b9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/SelectLanguageDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/SelectLanguageDialog.java @@ -19,12 +19,11 @@ import docking.DialogComponentProvider; import docking.DockingWindowManager; import ghidra.plugin.importer.NewLanguagePanel; import ghidra.program.model.lang.LanguageCompilerSpecPair; -import ghidra.util.SystemUtilities; +import ghidra.util.Swing; public class SelectLanguageDialog extends DialogComponentProvider { private NewLanguagePanel languagePanel; - private boolean actionComplete = false; private LanguageCompilerSpecPair selectedLcsPair; private boolean wasCancelled = false; @@ -47,7 +46,6 @@ public class SelectLanguageDialog extends DialogComponentProvider { @Override protected void okCallback() { if (checkInput()) { - actionComplete = true; selectedLcsPair = languagePanel.getSelectedLcsPair(); close(); } @@ -74,18 +72,14 @@ public class SelectLanguageDialog extends DialogComponentProvider { } void setSelectedLanguage(LanguageCompilerSpecPair language) { - SystemUtilities.runSwingNow(() -> languagePanel.setSelectedLcsPair(language)); + Swing.runNow(() -> languagePanel.setSelectedLcsPair(language)); } public LanguageCompilerSpecPair getSelectedLanguage() { - - SystemUtilities.runSwingNow(() -> showDialog()); return selectedLcsPair; } - private void showDialog() { - selectedLcsPair = null; - actionComplete = false; + public void show() { DockingWindowManager.showDialog(null, this); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java index 59491f513f..8fbbbeb67d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java @@ -32,10 +32,12 @@ import docking.widgets.label.GDLabel; import docking.widgets.label.GLabel; import docking.widgets.tree.support.GTreeSelectionEvent; import docking.widgets.tree.support.GTreeSelectionListener; +import ghidra.framework.main.datatree.DialogProjectTreeContext; import ghidra.framework.main.datatree.ProjectDataTreePanel; import ghidra.framework.main.projectdata.actions.*; import ghidra.framework.model.*; import ghidra.util.Msg; +import ghidra.util.Swing; import ghidra.util.exception.AssertException; import ghidra.util.layout.PairLayout; @@ -56,8 +58,7 @@ public class DataTreeDialog extends DialogComponentProvider /** * Dialog type for choosing a user folder. */ - public final static int CHOOSE_FOLDER = 2; // choose only a - // folder owned by the user + public final static int CHOOSE_FOLDER = 2; /** * Dialog type for creating domain data files. */ @@ -85,9 +86,9 @@ public class DataTreeDialog extends DialogComponentProvider private String pendingNameText; private DomainFolder pendingDomainFolder; - private ProjectDataExpandAction expandAction; - private ProjectDataCollapseAction collapseAction; - private ProjectDataNewFolderAction newFolderAction; + private ProjectDataExpandAction expandAction; + private ProjectDataCollapseAction collapseAction; + private ProjectDataNewFolderAction newFolderAction; private Integer treeSelectionMode; @@ -188,15 +189,22 @@ public class DataTreeDialog extends DialogComponentProvider return treePanel.getActionContext(null, event); } - public void showComponent() { + public void show() { doSetup(); DockingWindowManager.showDialog(parent, this); } + /** + * Shows this dialog. The preferred show method is {@link #show()}, as it is the preferred + * nomenclature. + */ + public void showComponent() { + show(); + } + @Override protected void dialogShown() { if (!comboModelInitialized) { - // make sure the combo box model has been populated doSetup(); } } @@ -255,9 +263,6 @@ public class DataTreeDialog extends DialogComponentProvider } } - /** - * Get the name from the name field. - */ public String getNameText() { return nameField.getText(); } @@ -275,7 +280,16 @@ public class DataTreeDialog extends DialogComponentProvider * @return null if there was no domain file selected */ public DomainFile getDomainFile() { - if (domainFile == null && !cancelled) { + + if (domainFile != null) { + return domainFile; + } + + if (cancelled) { + return null; + } + + if (treePanel != null) { domainFile = treePanel.getSelectedDomainFile(); } return domainFile; @@ -293,8 +307,7 @@ public class DataTreeDialog extends DialogComponentProvider } /** - * TreeSelectionListener method that is called whenever the value of the - * selection changes. + * TreeSelectionListener method that is called whenever the value of the selection changes. * @param e the event that characterizes the change. */ @Override @@ -364,31 +377,23 @@ public class DataTreeDialog extends DialogComponentProvider setOkEnabled((text != null) && !text.isEmpty()); } - /** - * Action listener for the project combo box. - * @param e event generated when a selection is made in the combo box - */ @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent event) { int index = projectComboBox.getSelectedIndex(); if (index < 0) { return; } - Project project = AppInfo.getActiveProject(); - try { - ProjectData pd = project.getProjectData(projectLocators[index]); - if (pd == null) { - Msg.showError(getClass(), getComponent(), "Error Getting Project Data", - "Could not get project data for " + projectLocators[index].getName()); - } - else { - treePanel.setProjectData(projectLocators[index].getName(), pd); - } + Project project = AppInfo.getActiveProject(); + ProjectLocator projectLocator = projectLocators[index]; + ProjectData pd = project.getProjectData(projectLocator); + String projectName = projectLocator.getName(); + if (pd == null) { + Msg.showError(this, getComponent(), "Error Getting Project Data", + "Could not get project data for " + projectName); } - catch (Exception exc) { - Msg.showError(getClass(), getComponent(), "Error Getting Project Data", exc.toString(), - exc); + else { + treePanel.setProjectData(projectName, pd); } } @@ -396,19 +401,17 @@ public class DataTreeDialog extends DialogComponentProvider * Select the root folder in the tree. */ public void selectRootDataFolder() { - SwingUtilities.invokeLater(() -> treePanel.selectRootDataFolder()); + Swing.runLater(() -> treePanel.selectRootDataFolder()); } /** * Select the node that corresponds to the given domain file. + * @param file the file */ - public void selectDomainFile(final DomainFile file) { - SwingUtilities.invokeLater(() -> treePanel.selectDomainFile(file)); + public void selectDomainFile(DomainFile file) { + Swing.runLater(() -> treePanel.selectDomainFile(file)); } - /* (non-Javadoc) - * @see docking.DialogComponentProvider#close() - */ @Override public void close() { super.close(); @@ -420,10 +423,6 @@ public class DataTreeDialog extends DialogComponentProvider comboModelInitialized = false; } - /** - * Define the Main panel for the dialog here. - * @return JPanel the completed Main Panel - */ protected JPanel buildMainPanel() { JPanel panel = new JPanel(); @@ -445,9 +444,6 @@ public class DataTreeDialog extends DialogComponentProvider return panel; } - /** - * Gets called when the user clicks on the OK Action for the dialog. - */ @Override protected void okCallback() { cancelled = false; @@ -463,17 +459,12 @@ public class DataTreeDialog extends DialogComponentProvider return cancelled; } - /** - * Called when user hits the cancel button. - */ @Override protected void cancelCallback() { cancelled = true; close(); } - ///////////////////////////////////////////////////////////////////// - /** * Create the data tree panel. */ @@ -653,13 +644,10 @@ public class DataTreeDialog extends DialogComponentProvider searchString = string; } - ///////////////////////////////////////////////////////////////////// private class FieldKeyListener extends KeyAdapter { - @Override public void keyPressed(KeyEvent e) { clearStatusText(); } } - } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java index af8f7bc57b..d6bd07420e 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java @@ -98,12 +98,10 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT // if we get here, then no exception happened--good! } - /** + /* * Test that askBytes method auto-populates dialog with value in .properties file. * * Also test that subsequent calls to the dialog show the last-used value. - * - * @throws Exception */ @Test public void testAskBytes() throws Exception { @@ -309,12 +307,10 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT assertEquals(anotherTempFile, myFile[0]); } - /** + /* * Test that askDirectory method auto-populates dialog with value in .properties file. * * Also test that subsequent calls to the dialog show the last-used value. - * - * @throws Exception */ @Test public void testAskDirectory() throws Exception { @@ -416,12 +412,10 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT FileUtilities.deleteDir(anotherTempSubDir); } - /** + /* * Test that askLanguage method auto-populates dialog with value in .properties file. * * Also test that subsequent calls to the dialog show the last-used value. - * - * @throws Exception */ @Test public void testAskLanguage() throws Exception { @@ -662,11 +656,9 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT assertEquals(choice_eenie, chosen); } - /** + /* * Test that askChoice method auto-populates dialog with user-supplied default value (in the * absence of a .properties file). - * - * @throws Exception */ @Test public void testAskChoiceDefaultValue() throws Exception { diff --git a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java index 5e608d3467..9ea0309e4e 100644 --- a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java +++ b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java @@ -171,6 +171,7 @@ public class PopulateFidDialog extends DialogComponentProvider { browseButton.addActionListener(e -> { SelectLanguageDialog selectLanguageDialog = new SelectLanguageDialog("Select Language", "Ok"); + selectLanguageDialog.show(); LanguageCompilerSpecPair selectedLanguage = selectLanguageDialog.getSelectedLanguage(); if (selectedLanguage != null) { languageIdField.setText(selectedLanguage.languageID.toString()); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/MultiLineMessageDialog.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/MultiLineMessageDialog.java index 2c2af26f0d..0be25f9e50 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/MultiLineMessageDialog.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/MultiLineMessageDialog.java @@ -28,6 +28,7 @@ import docking.widgets.OptionDialog; import docking.widgets.label.GIconLabel; import docking.widgets.label.GLabel; import ghidra.util.HTMLUtilities; +import ghidra.util.Swing; public class MultiLineMessageDialog extends DialogComponentProvider { /** Used for error messages. */ @@ -61,16 +62,21 @@ public class MultiLineMessageDialog extends DialogComponentProvider { */ public static void showModalMessageDialog(Component parent, String title, String shortMessage, String detailedMessage, int messageType) { - MultiLineMessageDialog mlmd = - new MultiLineMessageDialog(title, shortMessage, detailedMessage, messageType, true); - DockingWindowManager.showDialog(parent, mlmd); + Swing.runNow(() -> { + MultiLineMessageDialog dialog = + new MultiLineMessageDialog(title, shortMessage, detailedMessage, messageType, true); + DockingWindowManager.showDialog(parent, dialog); + }); } public static void showMessageDialog(Component parent, String title, String shortMessage, String detailedMessage, int messageType) { - MultiLineMessageDialog mlmd = - new MultiLineMessageDialog(title, shortMessage, detailedMessage, messageType, false); - DockingWindowManager.showDialog(parent, mlmd); + Swing.runNow(() -> { + MultiLineMessageDialog dialog = + new MultiLineMessageDialog(title, shortMessage, detailedMessage, messageType, + false); + DockingWindowManager.showDialog(parent, dialog); + }); } /**