From 2f58ec7b47d3e9a44f2706e8193c983c7500ab57 Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Wed, 22 May 2019 14:38:33 -0400 Subject: [PATCH] GT-2886 - fixed NPE when trying to beep --- .../CodeBrowserClipboardProvider.java | 12 +++------ .../main/java/ghidra/app/util/ByteCopier.java | 15 +++++------ .../ByteViewerClipboardProvider.java | 6 ++--- .../functiongraph/FGClipboardProvider.java | 3 +-- .../feature/vt/gui/plugin/VTPlugin.java | 5 ++-- .../java/docking/DockingWindowManager.java | 26 ++++++++++++++++++- .../docking/action/MultipleKeyAction.java | 8 +++--- .../framework/plugintool/PluginTool.java | 17 +++++++----- 8 files changed, 53 insertions(+), 39 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clipboard/CodeBrowserClipboardProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clipboard/CodeBrowserClipboardProvider.java index 15dee13241..04df545c3a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clipboard/CodeBrowserClipboardProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clipboard/CodeBrowserClipboardProvider.java @@ -173,8 +173,7 @@ public class CodeBrowserClipboardProvider extends ByteCopier return pasteByteString(string); } - tool.setStatusInfo("Paste failed: unsupported data type"); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo("Paste failed: unsupported data type", true); } catch (Exception e) { String msg = e.getMessage(); @@ -182,8 +181,7 @@ public class CodeBrowserClipboardProvider extends ByteCopier msg = e.toString(); Msg.error(this, "Unexpected Exception: " + e.getMessage(), e); } - tool.setStatusInfo("Paste failed: " + msg); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo("Paste failed: " + msg, true); } return false; } @@ -405,8 +403,7 @@ public class CodeBrowserClipboardProvider extends ByteCopier String message = "Copy failed: " + msg; Msg.error(this, message, e); - tool.setStatusInfo(message); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo(message, true); } return null; @@ -440,8 +437,7 @@ public class CodeBrowserClipboardProvider extends ByteCopier if (msg == null) { msg = e.toString(); } - tool.setStatusInfo("Paste failed: " + msg); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo("Paste failed: " + msg, true); } return false; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/ByteCopier.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/ByteCopier.java index c56ca18b5b..7bec236ec0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/ByteCopier.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/ByteCopier.java @@ -125,8 +125,7 @@ public abstract class ByteCopier { String string = (String) object; if (!isOnlyAsciiBytes(string)) { tool.setStatusInfo("Paste string contains non-text ascii bytes. " + - "Only the ascii text will be pasted."); - tool.getToolFrame().getToolkit().beep(); + "Only the ascii text will be pasted.", true); string = keepOnlyAsciiBytes(string); } @@ -219,8 +218,7 @@ public abstract class ByteCopier { protected boolean pasteBytes(Transferable pasteData) throws UnsupportedFlavorException, IOException { if (!supportsPasteTransferable(pasteData)) { - tool.setStatusInfo("Paste failed: No valid data on clipboard"); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo("Paste failed: No valid data on clipboard", true); return false; } @@ -249,8 +247,7 @@ public abstract class ByteCopier { String validString = string; if (!isOnlyAsciiBytes(string)) { tool.setStatusInfo("Pasted string contained non-text ascii bytes. " + - "Only the ascii text was pasted."); - tool.getToolFrame().getToolkit().beep(); + "Only the ascii text was pasted.", true); validString = keepOnlyAsciiBytes(string); } @@ -258,7 +255,7 @@ public abstract class ByteCopier { byte[] bytes = getBytes(validString); if (bytes == null) { status = "Improper data format (expected sequence of hex bytes)"; - tool.getToolFrame().getToolkit().beep(); + tool.beep(); return false; } @@ -270,13 +267,13 @@ public abstract class ByteCopier { for (int i = 0; i < byteCount;) { if (curAddr == null) { status = "Not enough addresses to paste bytes"; - tool.getToolFrame().getToolkit().beep(); + tool.beep(); return false; } CodeUnit curCodeUnit = listing.getCodeUnitContaining(curAddr); if (!(curCodeUnit instanceof Data) || ((Data) curCodeUnit).isDefined()) { status = "Cannot paste on top of defined instructions/data"; - tool.getToolFrame().getToolkit().beep(); + tool.beep(); return false; } int length = curCodeUnit.getLength(); diff --git a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerClipboardProvider.java b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerClipboardProvider.java index 7393fc7230..3edbd252b8 100644 --- a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerClipboardProvider.java +++ b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteViewerClipboardProvider.java @@ -86,8 +86,7 @@ public class ByteViewerClipboardProvider extends ByteCopier @Override public boolean paste(Transferable pasteData) { if (!supportsPasteTransferable(pasteData)) { - tool.setStatusInfo("Paste failed: No valid data on clipboard"); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo("Paste failed: No valid data on clipboard", true); return false; } @@ -96,8 +95,7 @@ public class ByteViewerClipboardProvider extends ByteCopier return pasteBytes(pasteData); } catch (Exception e) { - tool.setStatusInfo("Paste failed: " + e.getMessage()); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo("Paste failed: " + e.getMessage(), true); } return false; } diff --git a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGClipboardProvider.java b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGClipboardProvider.java index f1ba1b11e2..f1f733145e 100644 --- a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGClipboardProvider.java +++ b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGClipboardProvider.java @@ -86,8 +86,7 @@ public class FGClipboardProvider extends CodeBrowserClipboardProvider { if (msg == null) { msg = e.toString(); } - tool.setStatusInfo("Copy failed: " + msg); - tool.getToolFrame().getToolkit().beep(); + tool.setStatusInfo("Copy failed: " + msg, true); } return null; diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java index d581f70a88..3ca1573024 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java @@ -159,8 +159,7 @@ public class VTPlugin extends Plugin { Preferences.setProperty(SHOW_HELP_PREFERENCE, "No"); Preferences.store(); - URL url = - ResourceManager.getResource("help/topics/VersionTrackingPlugin/VT_Workflow.html"); + URL url = ResourceManager.getResource("help/topics/VersionTrackingPlugin/VT_Workflow.html"); if (url == null) { Msg.showError(this, null, "Help Not Found", "Unable to find the Version Tracking workflow help"); @@ -396,7 +395,7 @@ public class VTPlugin extends Plugin { */ static void showBusyToolMessage(PluginTool tool) { JFrame toolFrame = tool.getToolFrame(); - toolFrame.getToolkit().beep(); + tool.beep(); Msg.showInfo(VTPlugin.class, toolFrame, "Tool \"" + tool.getName() + "\" Busy", "You must stop all background tasks before exiting."); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java b/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java index e8fd9e41e4..8b820875a4 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java @@ -1909,7 +1909,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder } /** - * Set the status text in the active component window. + * Set the status text in the active component window * @param text status text */ public void setStatusText(String text) { @@ -1918,6 +1918,30 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder } } + /** + * Set the status text in the active component window + * + * @param text string to be displayed in the Status display area + * @param beep whether to beep or not + */ + public void setStatusText(String text, boolean beep) { + if (root == null) { + return; + } + + setStatusText(text); + if (beep) { + Toolkit.getDefaultToolkit().beep(); + } + } + + /** + * A convenience method to make an attention-grabbing noise to the user + */ + public static void beep() { + Toolkit.getDefaultToolkit().beep(); + } + /** * Set the menu group associated with a cascaded submenu. This allows * a cascading menu item to be grouped with a specific set of actions. diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java b/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java index a588c091b1..a57fc703df 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/action/MultipleKeyAction.java @@ -21,7 +21,7 @@ import java.util.*; import javax.swing.*; import docking.*; -import ghidra.util.SystemUtilities; +import ghidra.util.Swing; /** * Action that manages multiple PluginActions mapped to this action's key binding. @@ -146,7 +146,6 @@ public class MultipleKeyAction extends DockingKeyBindingAction { } // If more than one action, prompt user for selection - JFrame rootFrame = winMgr.getRootFrame(); if (list.size() > 1) { // popup dialog to show multiple actions if (dialog == null) { @@ -159,7 +158,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction { // doing the show in an invoke later seems to fix a strange swing bug that lock up // the program if you tried to invoke a new action too quickly after invoking // it the first time - SystemUtilities.runSwingLater(() -> winMgr.showDialog(dialog)); + Swing.runLater(() -> DockingWindowManager.showDialog(dialog)); } else if (list.size() == 1) { final ExecutableKeyActionAdapter actionProxy = list.get(0); @@ -168,8 +167,7 @@ public class MultipleKeyAction extends DockingKeyBindingAction { } else { String name = (String) getValue(Action.NAME); - winMgr.setStatusText("Action (" + name + ") not valid in this context!"); - rootFrame.getToolkit().beep(); + winMgr.setStatusText("Action (" + name + ") not valid in this context!", true); } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java index f8e11d24c2..b3ffe11734 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java @@ -492,14 +492,10 @@ public abstract class PluginTool extends AbstractDockingTool /** * Set the status information. * @param text string to be displayed in the Status display area - * @param beep whether to be or not + * @param beep whether to beep or not */ public void setStatusInfo(String text, boolean beep) { - winMgr.setStatusText(text); - if (beep) { - Toolkit tk = getToolFrame().getToolkit(); - tk.beep(); - } + winMgr.setStatusText(text, beep); } @Override @@ -514,6 +510,13 @@ public abstract class PluginTool extends AbstractDockingTool winMgr.setStatusText(""); } + /** + * A convenience method to make an attention-grabbing noise to the user + */ + public void beep() { + DockingWindowManager.beep(); + } + /** * Sets the provider that should get the default focus when no component has focus. * @param provider the provider that should get the default focus when no component has focus. @@ -1357,7 +1360,7 @@ public abstract class PluginTool extends AbstractDockingTool taskMgr.stop(false); } else { - getToolFrame().getToolkit().beep(); + beep(); Msg.showInfo(getClass(), getToolFrame(), "Tool Busy", "You must stop all background tasks before exiting."); return false;