Close the client's dialogs with Escape

Only the option-pane prompts closed on Escape, because Swing installs
that binding on the option pane itself. Dialogs.closeOnEscape puts the
same window-wide binding on a dialog's root pane, routed to whatever
that dialog does when its Close or Cancel button is pressed — reverting
the live-previewing settings, or flushing the bookmark being edited.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 14:36:17 +00:00
parent 0f8de796ea
commit 69003ced9a
8 changed files with 59 additions and 25 deletions

View File

@@ -0,0 +1,44 @@
package com.ts3client.ui;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
/** Behaviour shared by the client's dialogs. */
final class Dialogs {
private Dialogs() {
}
/**
* Makes Escape close a dialog, the way Swing's own option panes do.
*
* <p>The binding lives on the root pane's window-wide input map, so it fires
* wherever the focus sits — but only where nothing nearer to the focused
* component claims Escape first, which is what leaves a table's or combo
* box's own "cancel the edit" behaviour intact.
*/
static void closeOnEscape(JDialog dialog) {
closeOnEscape(dialog, dialog::dispose);
}
/**
* Binds Escape to the dialog's own way of closing, for dialogs that have to
* tidy up (or discard edits) on the way out.
*/
static void closeOnEscape(JDialog dialog, Runnable close) {
JRootPane root = dialog.getRootPane();
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ts3-close");
root.getActionMap().put("ts3-close", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
close.run();
}
});
}
}