diff --git a/docker/chrome/chrome.yaml b/docker/chrome/chrome.yaml index 37d8227151a..c9c6369c4a2 100644 --- a/docker/chrome/chrome.yaml +++ b/docker/chrome/chrome.yaml @@ -16,10 +16,10 @@ jobs: tests: - name: "At least one URL found" onFail: "WARN" - statistic: "spiderAjax.urls.added" + statistic: "stats.client.spider.urls" site: "" operator: ">=" value: 1 type: "stats" - name: "spiderAjax" - type: "spiderAjax" \ No newline at end of file + name: "spiderClient" + type: "spiderClient" \ No newline at end of file diff --git a/zap/src/main/java/org/parosproxy/paros/extension/AbstractDialog.java b/zap/src/main/java/org/parosproxy/paros/extension/AbstractDialog.java index b145e7267df..f6bf326d6c3 100644 --- a/zap/src/main/java/org/parosproxy/paros/extension/AbstractDialog.java +++ b/zap/src/main/java/org/parosproxy/paros/extension/AbstractDialog.java @@ -36,9 +36,11 @@ import java.awt.HeadlessException; import java.awt.Window; import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; import javax.swing.AbstractAction; +import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.KeyStroke; @@ -54,6 +56,8 @@ public abstract class AbstractDialog extends JDialog { protected AbstractDialog thisDialog = null; + private JButton defaultButton; + /** * Constructs an {@code AbstractDialog} with no owner and not modal. * @@ -114,6 +118,39 @@ public void actionPerformed(ActionEvent e) { }; getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escape, "ESCAPE"); getRootPane().getActionMap().put("ESCAPE", escapeAction); + + // Handle ctrl+enter to trigger the dialog's default button, regardless of which + // component (e.g. a text area or table) currently has focus. + KeyStroke ctrlEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK); + AbstractAction ctrlEnterAction = + new AbstractAction() { + private static final long serialVersionUID = 1L; + + @Override + public void actionPerformed(ActionEvent e) { + JButton button = getRootPane().getDefaultButton(); + if (button != null && button.isEnabled()) { + button.doClick(); + } + } + }; + getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlEnter, "CTRL_ENTER"); + getRootPane().getActionMap().put("CTRL_ENTER", ctrlEnterAction); + } + + /** + * Sets the button to use as this dialog's main action (e.g. OK, Apply, Save), giving it the + * current look and feel's "default button" highlight and binding it to Ctrl+Enter. + * + *

Disposing a dialog clears its root pane's default button (see {@link + * JButton#removeNotify()}), so this is re-applied every time the dialog is shown, which matters + * for dialogs that are constructed once and reused across multiple show/dispose cycles. + * + * @param button the button to use as this dialog's main action, or {@code null} for none. + */ + protected void setDefaultButton(JButton button) { + this.defaultButton = button; + getRootPane().setDefaultButton(button); } /** @@ -132,6 +169,7 @@ public void setVisible(boolean show) { == 0) { centreDialog(); } + getRootPane().setDefaultButton(defaultButton); } super.setVisible(show); } diff --git a/zap/src/main/java/org/parosproxy/paros/extension/history/ExtensionHistory.java b/zap/src/main/java/org/parosproxy/paros/extension/history/ExtensionHistory.java index 338bac3cee4..072e055aa0c 100644 --- a/zap/src/main/java/org/parosproxy/paros/extension/history/ExtensionHistory.java +++ b/zap/src/main/java/org/parosproxy/paros/extension/history/ExtensionHistory.java @@ -942,6 +942,7 @@ public void purgeHistory(List hrefs) { " ", removeWithoutConfirmationCheckBox }; + String confirmButtonLabel = Constant.messages.getString("history.purge.confirm"); int result = JOptionPane.showOptionDialog( View.getSingleton().getMainFrame(), @@ -951,10 +952,10 @@ public void purgeHistory(List hrefs) { JOptionPane.QUESTION_MESSAGE, null, new String[] { - Constant.messages.getString("history.purge.confirm"), + confirmButtonLabel, Constant.messages.getString("history.purge.cancel") }, - null); + confirmButtonLabel); if (result != JOptionPane.YES_OPTION) { return; } diff --git a/zap/src/main/java/org/parosproxy/paros/extension/option/OptionsConnectionPanel.java b/zap/src/main/java/org/parosproxy/paros/extension/option/OptionsConnectionPanel.java index 4cfa5b4463e..cb46e7b50f4 100644 --- a/zap/src/main/java/org/parosproxy/paros/extension/option/OptionsConnectionPanel.java +++ b/zap/src/main/java/org/parosproxy/paros/extension/option/OptionsConnectionPanel.java @@ -1002,7 +1002,7 @@ public boolean showRemoveDialogue(DomainMatcher e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/parosproxy/paros/view/AbstractParamDialog.java b/zap/src/main/java/org/parosproxy/paros/view/AbstractParamDialog.java index 0b8c1963f97..4c24bed04bf 100644 --- a/zap/src/main/java/org/parosproxy/paros/view/AbstractParamDialog.java +++ b/zap/src/main/java/org/parosproxy/paros/view/AbstractParamDialog.java @@ -177,6 +177,7 @@ private javax.swing.JPanel getJContentPane() { GridBagConstraints.NONE, GridBagConstraints.EAST, new Insets(2, 2, 2, 2))); + this.setDefaultButton(getBtnOK()); jContentPane.add(footerPane, LayoutHelper.getGBC(0, 1, 1, 1.0, 0.0)); } diff --git a/zap/src/main/java/org/parosproxy/paros/view/FindDialog.java b/zap/src/main/java/org/parosproxy/paros/view/FindDialog.java index 23eea0174b2..9cb943c3044 100644 --- a/zap/src/main/java/org/parosproxy/paros/view/FindDialog.java +++ b/zap/src/main/java/org/parosproxy/paros/view/FindDialog.java @@ -134,7 +134,7 @@ private void initialize() { this.setContentPane(getJPanel()); centreDialog(); txtFind.requestFocus(); - this.getRootPane().setDefaultButton(btnFind); + this.setDefaultButton(getBtnFind()); pack(); this.setVisible(true); } diff --git a/zap/src/main/java/org/parosproxy/paros/view/SiteMapPanel.java b/zap/src/main/java/org/parosproxy/paros/view/SiteMapPanel.java index b6e2633f086..81164d355b4 100644 --- a/zap/src/main/java/org/parosproxy/paros/view/SiteMapPanel.java +++ b/zap/src/main/java/org/parosproxy/paros/view/SiteMapPanel.java @@ -471,6 +471,8 @@ public void actionPerformed(ActionEvent e) { " ", removeWithoutConfirmationCheckBox }; + String confirmButtonLabel = + Constant.messages.getString("sites.purge.confirm"); int result = JOptionPane.showOptionDialog( View.getSingleton().getMainFrame(), @@ -481,12 +483,11 @@ public void actionPerformed(ActionEvent e) { JOptionPane.QUESTION_MESSAGE, null, new String[] { - Constant.messages.getString( - "sites.purge.confirm"), + confirmButtonLabel, Constant.messages.getString( "sites.purge.cancel") }, - null); + confirmButtonLabel); if (result != JOptionPane.YES_OPTION) { return; } diff --git a/zap/src/main/java/org/zaproxy/zap/extension/alert/AlertAddDialog.java b/zap/src/main/java/org/zaproxy/zap/extension/alert/AlertAddDialog.java index e7c3dd372f7..5a14ff8a983 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/alert/AlertAddDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/alert/AlertAddDialog.java @@ -167,6 +167,7 @@ private JPanel getJPanel() { jPanel.add(jLabel2, gridBagConstraints13); jPanel.add(getBtnCancel(), gridBagConstraints2); jPanel.add(getBtnOk(), gridBagConstraints3); + this.setDefaultButton(getBtnOk()); } return jPanel; } diff --git a/zap/src/main/java/org/zaproxy/zap/extension/anticsrf/OptionsAntiCsrfPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/anticsrf/OptionsAntiCsrfPanel.java index 9232e11692d..8786bbc2569 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/anticsrf/OptionsAntiCsrfPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/anticsrf/OptionsAntiCsrfPanel.java @@ -197,7 +197,7 @@ public boolean showRemoveDialogue(AntiCsrfParamToken e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/api/ExtensionAPI.java b/zap/src/main/java/org/zaproxy/zap/extension/api/ExtensionAPI.java index f7397e87725..a49d7f6c62d 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/api/ExtensionAPI.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/api/ExtensionAPI.java @@ -115,7 +115,7 @@ public void actionPerformed(java.awt.event.ActionEvent e) { new String[] { confirmButtonLabel, cancelButtonLabel }, - null); + confirmButtonLabel); if (option != JOptionPane.YES_OPTION) { return; diff --git a/zap/src/main/java/org/zaproxy/zap/extension/api/OptionsApiPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/api/OptionsApiPanel.java index 650f9eb03cc..6a0a2a71c81 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/api/OptionsApiPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/api/OptionsApiPanel.java @@ -479,7 +479,7 @@ public boolean showRemoveDialogue(DomainMatcher e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/ascan/OptionsVariantPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/ascan/OptionsVariantPanel.java index ed2ed7a37cc..d45333bf05d 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/ascan/OptionsVariantPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/ascan/OptionsVariantPanel.java @@ -887,7 +887,7 @@ public boolean showRemoveDialogue(ScannerParamFilter e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); return (option == JOptionPane.OK_OPTION); } diff --git a/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/ManageAddOnsDialog.java b/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/ManageAddOnsDialog.java index d11e93e3723..286d1cd9dc0 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/ManageAddOnsDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/ManageAddOnsDialog.java @@ -205,6 +205,17 @@ public void actionPerformed(ActionEvent e) { getRootPane().getActionMap().put("ESCAPE", escapeAction); } + @Override + public void setVisible(boolean visible) { + if (visible) { + // This dialog is created once and reused, and disposing it (as the close buttons do) + // clears the root pane's default button (see JButton#removeNotify()), so it must be + // re-applied every time the dialog is shown. + getRootPane().setDefaultButton(getCheckForUpdatesButton()); + } + super.setVisible(visible); + } + private JPanel getTopPanel() { if (topPanel == null) { topPanel = new JPanel(); @@ -266,6 +277,7 @@ private JPanel getCorePanel(boolean update) { corePanel.add(new JLabel(this.currentVersion), LayoutHelper.getGBC(0, 0, 1, 0.0D)); corePanel.add(new JLabel(""), LayoutHelper.getGBC(1, 0, 1, 1.0D)); corePanel.add(this.getCheckForUpdatesButton(), LayoutHelper.getGBC(2, 0, 1, 0.0D)); + getRootPane().setDefaultButton(this.getCheckForUpdatesButton()); refresh = false; } } else if (latestInfo != null && this.latestInfo.getZapRelease() != null) { diff --git a/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/OptionsCheckForUpdatesPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/OptionsCheckForUpdatesPanel.java index ea787fa0086..af91df7d42a 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/OptionsCheckForUpdatesPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/autoupdate/OptionsCheckForUpdatesPanel.java @@ -444,7 +444,7 @@ public boolean showRemoveDialogue(File f) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/brk/BreakPanelToolbarFactory.java b/zap/src/main/java/org/zaproxy/zap/extension/brk/BreakPanelToolbarFactory.java index 127ae829ae4..b2c44209b2c 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/brk/BreakPanelToolbarFactory.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/brk/BreakPanelToolbarFactory.java @@ -254,7 +254,7 @@ private int askForDropConfirmation() { JOptionPane.QUESTION_MESSAGE, null, new String[] {confirmButtonLabel, cancelButtonLabel}, - null); + confirmButtonLabel); if (checkBox.isSelected()) { breakpointsParams.setConfirmDropMessage(false); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/custompages/ContextCustomPagePanel.java b/zap/src/main/java/org/zaproxy/zap/extension/custompages/ContextCustomPagePanel.java index 2a33cb6b1ac..1e86eddd6ba 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/custompages/ContextCustomPagePanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/custompages/ContextCustomPagePanel.java @@ -183,7 +183,7 @@ public boolean showRemoveDialogue(CustomPage customPage) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/globalexcludeurl/OptionsGlobalExcludeURLPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/globalexcludeurl/OptionsGlobalExcludeURLPanel.java index 5628e81473f..2c874ead360 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/globalexcludeurl/OptionsGlobalExcludeURLPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/globalexcludeurl/OptionsGlobalExcludeURLPanel.java @@ -210,7 +210,7 @@ public boolean showRemoveDialogue(GlobalExcludeURLParamToken e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/history/HistoryFilterPlusDialog.java b/zap/src/main/java/org/zaproxy/zap/extension/history/HistoryFilterPlusDialog.java index ee83abcb03b..94b2cd1afad 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/history/HistoryFilterPlusDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/history/HistoryFilterPlusDialog.java @@ -125,7 +125,7 @@ private void initialize() { this.setSize(600, 300); } centreDialog(); - this.getRootPane().setDefaultButton(btnApply); + this.setDefaultButton(getBtnApply()); this.pack(); } diff --git a/zap/src/main/java/org/zaproxy/zap/extension/history/ManageTagsDialog.java b/zap/src/main/java/org/zaproxy/zap/extension/history/ManageTagsDialog.java index 0c585470ef1..e158f12d5f0 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/history/ManageTagsDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/history/ManageTagsDialog.java @@ -172,6 +172,7 @@ private JPanel getJPanel() { jPanel.add(getBtnDelete(), gridBagConstraints31); jPanel.add(getBtnCancel(), gridBagConstraints40); jPanel.add(getBtnSave(), gridBagConstraints41); + this.setDefaultButton(getBtnSave()); } return jPanel; } diff --git a/zap/src/main/java/org/zaproxy/zap/extension/history/NotesAddDialog.java b/zap/src/main/java/org/zaproxy/zap/extension/history/NotesAddDialog.java index f8e335fa4cc..503c6583d68 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/history/NotesAddDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/history/NotesAddDialog.java @@ -100,6 +100,8 @@ private void initialize() { setContentPane(panel); + this.setDefaultButton(getBtnOk()); + this.addWindowListener( new java.awt.event.WindowAdapter() { diff --git a/zap/src/main/java/org/zaproxy/zap/extension/history/PopupMenuPurgeSites.java b/zap/src/main/java/org/zaproxy/zap/extension/history/PopupMenuPurgeSites.java index bdf285416a1..cdeecf9f27d 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/history/PopupMenuPurgeSites.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/history/PopupMenuPurgeSites.java @@ -77,6 +77,7 @@ public void performHistoryReferenceActions(List hrefs) { " ", removeWithoutConfirmationCheckBox }; + String confirmButtonLabel = Constant.messages.getString("sites.purge.confirm"); int result = JOptionPane.showOptionDialog( View.getSingleton().getMainFrame(), @@ -86,10 +87,10 @@ public void performHistoryReferenceActions(List hrefs) { JOptionPane.QUESTION_MESSAGE, null, new String[] { - Constant.messages.getString("sites.purge.confirm"), + confirmButtonLabel, Constant.messages.getString("sites.purge.cancel") }, - null); + confirmButtonLabel); if (result != JOptionPane.YES_OPTION) { return; } diff --git a/zap/src/main/java/org/zaproxy/zap/extension/httpsessions/OptionsHttpSessionsPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/httpsessions/OptionsHttpSessionsPanel.java index 6255131d5f5..084b6eb61c5 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/httpsessions/OptionsHttpSessionsPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/httpsessions/OptionsHttpSessionsPanel.java @@ -218,7 +218,7 @@ public boolean showRemoveDialogue(HttpSessionToken e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/proxies/OptionsProxiesPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/proxies/OptionsProxiesPanel.java index 1d06ceb7d11..530449fac8b 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/proxies/OptionsProxiesPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/proxies/OptionsProxiesPanel.java @@ -257,7 +257,7 @@ public boolean showRemoveDialogue(ProxiesParamProxy e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/pscan/OptionsPassiveScan.java b/zap/src/main/java/org/zaproxy/zap/extension/pscan/OptionsPassiveScan.java index 12b7a6a6aa7..5e1b4141dd6 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/pscan/OptionsPassiveScan.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/pscan/OptionsPassiveScan.java @@ -193,7 +193,7 @@ public boolean showRemoveDialogue( REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/script/OptionsScriptPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/script/OptionsScriptPanel.java index 4fde31054ab..bd532e228a1 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/script/OptionsScriptPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/script/OptionsScriptPanel.java @@ -203,7 +203,7 @@ public boolean showRemoveDialogue(File f) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/extension/search/SearchPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/search/SearchPanel.java index 380e9e2bd95..33d0b5b4693 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/search/SearchPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/search/SearchPanel.java @@ -468,6 +468,9 @@ private void doSearch() { } if (pattern.matcher("").find()) { + String searchButtonLabel = + Constant.messages.getString( + "search.toolbar.warn.regex.match.empty.string.button.search"); int option = JOptionPane.showOptionDialog( View.getSingleton().getMainFrame(), @@ -479,12 +482,11 @@ private void doSearch() { JOptionPane.QUESTION_MESSAGE, null, new String[] { - Constant.messages.getString( - "search.toolbar.warn.regex.match.empty.string.button.search"), + searchButtonLabel, Constant.messages.getString( "search.toolbar.warn.regex.match.empty.string.button.cancel") }, - null); + searchButtonLabel); if (option != JOptionPane.OK_OPTION) { regEx.requestFocusInWindow(); return; diff --git a/zap/src/main/java/org/zaproxy/zap/extension/users/ContextUsersPanel.java b/zap/src/main/java/org/zaproxy/zap/extension/users/ContextUsersPanel.java index 523b706bc83..43a5d27233c 100644 --- a/zap/src/main/java/org/zaproxy/zap/extension/users/ContextUsersPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/extension/users/ContextUsersPanel.java @@ -171,7 +171,7 @@ public boolean showRemoveDialogue(User e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/view/AbstractFormDialog.java b/zap/src/main/java/org/zaproxy/zap/view/AbstractFormDialog.java index c951fb9363d..ed2a086aaa4 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/AbstractFormDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/view/AbstractFormDialog.java @@ -28,6 +28,7 @@ import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; @@ -114,6 +115,25 @@ public void actionPerformed(ActionEvent e) { }; getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escape, "ESCAPE"); getRootPane().getActionMap().put("ESCAPE", escapeAction); + + // Handle ctrl+enter to trigger the dialog's default button, regardless of which + // component (e.g. a text area or table) currently has focus. + KeyStroke ctrlEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK); + AbstractAction ctrlEnterAction = + new AbstractAction() { + + private static final long serialVersionUID = 1L; + + @Override + public void actionPerformed(ActionEvent e) { + JButton button = getRootPane().getDefaultButton(); + if (button != null && button.isEnabled()) { + button.doClick(); + } + } + }; + getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlEnter, "CTRL_ENTER"); + getRootPane().getActionMap().put("CTRL_ENTER", ctrlEnterAction); } protected void initView() { @@ -206,6 +226,14 @@ public void setVisible(boolean b) { firstTime = false; } + if (b) { + // Disposing the dialog clears the root pane's default button (see + // JButton#removeNotify()), so it must be re-applied every time the dialog is shown, + // which matters for dialogs that are constructed once and reused across multiple + // show/dispose cycles. + getRootPane().setDefaultButton(getConfirmButton()); + } + super.setVisible(b); } diff --git a/zap/src/main/java/org/zaproxy/zap/view/ContextStructurePanel.java b/zap/src/main/java/org/zaproxy/zap/view/ContextStructurePanel.java index b1a037ce080..0e59c1ed4ba 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/ContextStructurePanel.java +++ b/zap/src/main/java/org/zaproxy/zap/view/ContextStructurePanel.java @@ -361,7 +361,7 @@ public boolean showRemoveDialogue(StructuralNodeModifier e) { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/view/LocaleDialog.java b/zap/src/main/java/org/zaproxy/zap/view/LocaleDialog.java index e8b5c1a40a8..1a4b64f7431 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/LocaleDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/view/LocaleDialog.java @@ -101,6 +101,7 @@ private JPanel getJPanel() { gridBagConstraints6.anchor = java.awt.GridBagConstraints.SOUTHEAST; jPanel.add(getViewPanel(), gridBagConstraints5); jPanel.add(getBtnOK(), gridBagConstraints6); + this.setDefaultButton(getBtnOK()); } return jPanel; } diff --git a/zap/src/main/java/org/zaproxy/zap/view/MultipleRegexesOptionsPanel.java b/zap/src/main/java/org/zaproxy/zap/view/MultipleRegexesOptionsPanel.java index a3c7c18339b..fb0d95bb756 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/MultipleRegexesOptionsPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/view/MultipleRegexesOptionsPanel.java @@ -243,7 +243,7 @@ public boolean showRemoveDialogue(String e) { new String[] { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { setRemoveWithoutConfirmation(removeWithoutConfirmationCheckBox.isSelected()); diff --git a/zap/src/main/java/org/zaproxy/zap/view/NodeSelectDialog.java b/zap/src/main/java/org/zaproxy/zap/view/NodeSelectDialog.java index faf0bd32b66..d3e9f0c340b 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/NodeSelectDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/view/NodeSelectDialog.java @@ -263,6 +263,7 @@ private JPanel getJPanel() { jPanel.add(jLabel2, gridBagConstraints13); jPanel.add(getCancelButton(), gridBagConstraints2); jPanel.add(getSelectButton(), gridBagConstraints3); + this.setDefaultButton(getSelectButton()); } return jPanel; } diff --git a/zap/src/main/java/org/zaproxy/zap/view/PersistSessionDialog.java b/zap/src/main/java/org/zaproxy/zap/view/PersistSessionDialog.java index 4b6f2d19bf3..5ddd4678d57 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/PersistSessionDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/view/PersistSessionDialog.java @@ -126,6 +126,7 @@ public void actionPerformed(ActionEvent e) { buttonPanel.add( getStartSessionButton(), LayoutHelper.getGBC(2, 0, 1, 0.0D, new Insets(4, 4, 4, 4))); + this.setDefaultButton(getStartSessionButton()); jPanel.add(buttonPanel, LayoutHelper.getGBC(0, 20, 2, 1.0D, new Insets(4, 4, 4, 4))); } diff --git a/zap/src/main/java/org/zaproxy/zap/view/ProxyDialog.java b/zap/src/main/java/org/zaproxy/zap/view/ProxyDialog.java index 7c9d1576206..93b74b02dc9 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/ProxyDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/view/ProxyDialog.java @@ -113,6 +113,7 @@ private JPanel getJPanel() { jPanel.add(getConnPanel(), gridBagConstraints5); // jPanel.add(getBtnCancel(), gridBagConstraints7); jPanel.add(getBtnOK(), gridBagConstraints6); + this.setDefaultButton(getBtnOK()); } return jPanel; } diff --git a/zap/src/main/java/org/zaproxy/zap/view/StandardFieldsDialog.java b/zap/src/main/java/org/zaproxy/zap/view/StandardFieldsDialog.java index d0650acbb16..adfc42a56f2 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/StandardFieldsDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/view/StandardFieldsDialog.java @@ -355,6 +355,7 @@ private void initContentPanel( contentPanel.add(getCancelButton(), LayoutHelper.getGBC(x, 1, 1, 0.0D)); } } + setDefaultButton(getSaveButton()); } /* diff --git a/zap/src/main/java/org/zaproxy/zap/view/ZapSupportDialog.java b/zap/src/main/java/org/zaproxy/zap/view/ZapSupportDialog.java index 64e3ca90bc5..664705d50e9 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/ZapSupportDialog.java +++ b/zap/src/main/java/org/zaproxy/zap/view/ZapSupportDialog.java @@ -129,7 +129,7 @@ private JPanel getMainPanel() { mainPanel.add(getBtnOpen(), gbcOpenButton); mainPanel.add(getBtnSaveSbom(), gbcSaveSbomButton); mainPanel.add(getBtnCopy(), gbcCopyButton); - this.getRootPane().setDefaultButton(getBtnCopy()); + this.setDefaultButton(getBtnCopy()); mainPanel.add(getBtnOK(), gbcOkButton); } return mainPanel; diff --git a/zap/src/main/java/org/zaproxy/zap/view/messagelocation/AbstractMessageLocationsPanel.java b/zap/src/main/java/org/zaproxy/zap/view/messagelocation/AbstractMessageLocationsPanel.java index fbe3db9d874..4cdcddc406b 100644 --- a/zap/src/main/java/org/zaproxy/zap/view/messagelocation/AbstractMessageLocationsPanel.java +++ b/zap/src/main/java/org/zaproxy/zap/view/messagelocation/AbstractMessageLocationsPanel.java @@ -264,7 +264,7 @@ protected boolean showRemoveDialogueImpl(T e) { new String[] { REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL }, - null); + REMOVE_DIALOG_CONFIRM_BUTTON_LABEL); if (option == JOptionPane.OK_OPTION) { getRemoveWithoutConfirmationCheckBox()