Java Swing Shift+F10 Accessibility - java

Per accessibility requirements, Shift+F10 is supposed to open right-click context menus.
In Swing, one approach is to just add the key binding to every component you make. However, I've experimented with extending the EventQueue to handle all Shift+F10 presses. In particular, I've overridden dispatchEvent(AWTEvent) to convert Shift+F10 KeyEvents into right-click mousePresses:
protected void dispatchEvent(AWTEvent event) {
if (event instanceof KeyEvent) {
KeyEvent ev = (KeyEvent) event;
if ((ev.getKeyCode() == KeyEvent.VK_F10) &&
(ev.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) > 0) {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component comp = kfm.getFocusOwner();
Point mouse = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(mouse, comp);
eventToDispatch = new MouseEvent(comp,
MouseEvent.MOUSE_RELEASED, ev.getWhen(), 0, mouse.x, mouse.y,
1, true);
}
}
}
However, this prevents Shift+F10 from being able to close any JPopupMenus that get launched. Any idea if this solution is workable, or are there better ways to accomplish meeting this requirement?

ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
try {
int dotPosition = textField.getCaretPosition();
Rectangle popupLocation = textField
.modelToView(dotPosition);
popup.show(textField, popupLocation.x, popupLocation.y);
} catch (BadLocationException badLocationException) {
System.out.println("Oops");
}
}
};
KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F10,
InputEvent.SHIFT_MASK);
textField.registerKeyboardAction(actionListener, keystroke,
JComponent.WHEN_FOCUSED);

Related

JRadioButton navigation with arrow keys

I am trying to get a group of JRadioButtons to be navigable using the arrow keys. I was going to implement this manually with KeyListeners, but apparently this behavior is already supposed to work for at least the last 8 years (http://bugs.sun.com/view_bug.do?bug_id=4104452). However, it's not working for me: pressing the arrow keys does nothing. Java version is 7u45 on Windows.
A standalone test case to see what I'm talking about:
import java.awt.*;
import javax.swing.*;
public class Test {
public static void main(final String[] args) {
if (!EventQueue.isDispatchThread()) {
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
main(args);
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
return;
}
try {
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
//UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Throwable t) {
throw new RuntimeException(t);
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ButtonGroup group = new ButtonGroup();
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
JRadioButton rb;
rb = new JRadioButton("Option A");
panel.add(rb);
group.add(rb);
rb = new JRadioButton("Option B");
panel.add(rb);
group.add(rb);
rb = new JRadioButton("Option C");
panel.add(rb);
group.add(rb);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
I have tried using different look & feels, different containers, and different layout managers, but it still does not work.
You need to add the right/left (up/down?) keys to the focus traversal policy of each radio button. For example to add the right/left arrow keys:
Set set = new HashSet( rb.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS ) );
set.add( KeyStroke.getKeyStroke( "RIGHT" ) );
rb.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set );
set = new HashSet( rb.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS ) );
set.add( KeyStroke.getKeyStroke( "LEFT" ) );
rb.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, set );
Read the section from the Swing tutorial on How to Use the Focus Subsystem for more information.
I believe you can achieve your goal using KeyBindings instead of KeyListeners. In many cases bindings are actually recommended over KeyListeners, as the second ones can generate many problems (frame catching the key activity must be active one etc.)
Thank you everyone for the answers.
I discovered the reason for my confusion. Apparently, when the Sun bug report system says that a bug's status is "Closed" and its "Resolved Date" is "2005-07-19", that doesn't mean the bug is fixed at all. Apparently, it's just logged as a duplicate of some other (newer?) bug. Nearly 16 years since it was first reported it still isn't fixed. Whatever.
The needed behavior is much more subtle than I realized. I experimented in native Windows dialogs in various programs:
Most button-like components: buttons, checkboxes, and radio buttons, implement the arrow keys for focus navigation. In Java this corresponds to the AbstractButton class. (JMenuItem is also a subclass of that, but that has its own distinct arrow key behavior.)
Only radio buttons get selected/checked during this navigation.
Unfocusable (including disabled or invisible) components must be skipped.
Attempting to navigate before the first button in a group or after the last one is inconsistent: on some dialogs it loops from end to end; on others it moves irreversibly onto non-button components; and on yet others it does nothing. I experimented with all these different behaviors and none of them was particularly better than the others.
I implemented a looping behavior below as it felt slightly more fluent. The navigation silently skips past non-AbstractButton components, forming a sort-of separate focus cycle private to buttons. This is dubious but sometimes needed when a set of related checkboxes or radio buttons are mixed with other components. Testing for a common parent component to identify groups would also be a reasonable behavior, but that didn't work in one dialog where I'd used separate components purely for layout reasons (to implement a line break in a FlowLayout).
As suggested I studied up on InputMaps and ActionMaps instead of using a KeyListener. I've always avoided the maps as they seem overcomplicated but I guess I see the advantage of being able to easily override the binding.
This code uses an auxialiary look and feel to install the desired behavior for all AbstractButton components application-wide (which is a nice technique I found out about here). I've tested it with several different dialog boxes and windows and it seems to be okay. If it causes issues I'll update this post.
Call:
ButtonArrowKeyNavigation.install();
once at application startup to install it.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonArrowKeyNavigation {
private ButtonArrowKeyNavigation() {}
public static void install() {
UIManager.addAuxiliaryLookAndFeel(lookAndFeel);
}
private static final LookAndFeel lookAndFeel = new LookAndFeel() {
private final UIDefaults defaults = new UIDefaults() {
#Override
public javax.swing.plaf.ComponentUI getUI(JComponent c) {
if (c instanceof AbstractButton && !(c instanceof JMenuItem)) {
if (c.getClientProperty(this) == null) {
c.putClientProperty(this, Boolean.TRUE);
configure(c);
}
}
return null;
}
};
#Override public UIDefaults getDefaults() { return defaults; };
#Override public String getID() { return "ButtonArrowKeyNavigation"; }
#Override public String getName() { return getID(); }
#Override public String getDescription() { return getID(); }
#Override public boolean isNativeLookAndFeel() { return false; }
#Override public boolean isSupportedLookAndFeel() { return true; }
};
private static void configure(JComponent c) {
InputMap im = c.getInputMap(JComponent.WHEN_FOCUSED);
ActionMap am = c.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "focusPreviousButton");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "focusPreviousButton");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "focusNextButton");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "focusNextButton");
am.put("focusPreviousButton", focusPreviousButton);
am.put("focusNextButton", focusNextButton);
}
private static final Action focusPreviousButton = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
move((AbstractButton)e.getSource(), -1);
}
};
private static final Action focusNextButton = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
move((AbstractButton)e.getSource(), +1);
}
};
private static void move(AbstractButton ab, int direction) {
Container focusRoot = ab.getFocusCycleRootAncestor();
FocusTraversalPolicy focusPolicy = focusRoot.getFocusTraversalPolicy();
Component toFocus = ab, loop = null;
for (;;) {
toFocus = direction > 0
? focusPolicy.getComponentAfter(focusRoot, toFocus)
: focusPolicy.getComponentBefore(focusRoot, toFocus);
if (toFocus instanceof AbstractButton) break;
if (toFocus == null) return;
// infinite loop protection; should not be necessary, but just in
// case all buttons are somehow unfocusable at the moment this
// method is called:
if (loop == null) loop = toFocus; else if (loop == toFocus) return;
}
if (toFocus.requestFocusInWindow()) {
if (toFocus instanceof JRadioButton) {
((JRadioButton)toFocus).setSelected(true);
}
}
}
}
Here is my example of JRadioButtons can be navigable using the arrow keys(UP and Down) and modified few codes for you.
public class JRadioButton extends JPanel {
private JRadioButton[] buttons;
public JRadioButtonTest(int row) {
ButtonGroup group = new ButtonGroup();
buttons = new JRadioButton[row];
for (int i = 0; i < buttons.length; i++) {
final int curRow = i;
buttons[i] = new JRadioButton("Option " + i);
buttons[i].addKeyListener(enter);
buttons[i].addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
if (curRow > 0)
buttons[curRow - 1].requestFocus();
break;
case KeyEvent.VK_DOWN:
if (curRow < buttons.length - 1)
buttons[curRow + 1].requestFocus();
break;
default:
break;
}
}
});
group.add(buttons[i]);
add(buttons[i]);
}
}
private KeyListener enter = new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_ENTER) {
((JButton) e.getComponent()).doClick();
}
}
};
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JRadioButton(3));
frame.pack();
frame.setVisible(true);
}
}
The core implement method is calling requestFocus() on the correct JRadioButton when an arrow key is called. Extra KeyListener for when the Enter key is pressed.
You can use this KeyListener to your program and add more key.
Good luck!

Where to addKeyListener in order to 'always' be listening

I need a keylistener to be always 'listening' for the escape key to be pressed, to then exit the program.
I have tried typing addKeyListener(this); in my main constructor (the one with the panel being drawn in) and have used
public void keyPressed( KeyEvent e)
{
int code = e.getKeyCode();
if(code == KeyEvent.VK_ESCAPE)
{
System.exit( 0 );
}
}
I get no errors, but pressing the escape key doesn't seem to do anything, any suggestions?
Top-Level Container by default never receiving KeyEvent from KeyListener, by default, but is possible with a few code lines, wrong idea, wrong listener
JPanel by defaul react to KeyEvent, but only in the case that isFocusable, is FocusOwner, wrong idea, wrong listener, (for example) because you needed to move Focus from JTextField to JPanel programatically, wrong idea
add KeyBindings to JFrame/ JDialog / JWindow, accesible by default for Swing JComponent, not for AWT Components
You can use the InputMap/ActionMap mechanism :
Object escapeActionKey = new Object();
pnl.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ESCAPE"), escapeActionKey);
pnl.getActionMap().put(escapeActionKey, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.err.println("escape 1");
}
});
JComponent.WHEN_IN_FOCUSED_WINDOW means that this keystroke is available when the pnl component is in the focused window.
Or you can also add a global AWTEventListener listener :
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
public void eventDispatched(AWTEvent event) {
if(event.getID() == KeyEvent.KEY_PRESSED) {
KeyEvent kEvent = (KeyEvent) event;
boolean isEsc = (kEvent.getKeyCode() == KeyEvent.VK_ESCAPE);
if(isEsc) {
System.err.println("escape 2");
}
}
}
}, AWTEvent.KEY_EVENT_MASK);
In Swing there is a top layer panel : the GlassPane which allow to handle event at top level (to avoid other widget to comsume the event)

How to Set Focus on JTextField?

I make my game run without mouse so using pointer is not a choice. High Score menu will show when player lose.
this is my code
highScore=new MyTextField("Your Name");
highScore.addKeyListener(this);
highScore.setFont(font);
highScore.requestFocusInWindow();
I have tried
highScore.setFocusable(true);
highScore.requestFocusInWindow();
highScore.requestFocus(true);
highScore.requestFocus();
but still not gained focus on my JTextField.
How to focus it?
If you want your JTextField to be focused when your GUI shows up, you can use this:
in = new JTextField(40);
f.addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
in.requestFocus();
}
});
Where f would be your JFrame and in is your JTextField.
if is there only one Top-Level Container then last lines in GUI constructor would be for example
.
.
.
myFrame.setVisible(true);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
myComponent.grabFocus();
myComponent.requestFocus();//or inWindow
}
});
public void actionPerformed(ActionEvent arg0)
{
if (arg0.getSource()==clearButton)
{
enterText.setText(null);
enterText.grabFocus(); //Places flashing cursor on text box
}
}
Try this one,
myFrame.setVisible(true);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
myComponent.grabFocus();
myComponent.requestFocus();//or inWindow
}
});
If the page contains multiple item and like to set the tab sequence and focus I will suggest to use FocusTraversalPolicy.
grabFocus() will not work if you are using FocusTraversalPolicy.
Sample code
int focusNumber = 0;
Component[] focusList;
focusList = new Component[] { game, move, amount, saveButton,
printButton, editButton, deleteButton, newButton,
settingsButton };
frame.setFocusTraversalPolicy(new FocusTraversalPolicy() {
#Override
public Component getLastComponent(Container aContainer) {
return focusList[focusList.length - 1];
}
#Override
public Component getFirstComponent(Container aContainer) {
return focusList[0];
}
#Override
public Component getDefaultComponent(Container aContainer) {
return focusList[1];
}
#Override
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
focusNumber = (focusNumber + 1) % focusList.length;
if (focusList[focusNumber].isEnabled() == false) {
getComponentAfter(focusCycleRoot, focusList[focusNumber]);
}
return focusList[focusNumber];
}
#Override
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
focusNumber = (focusList.length + focusNumber - 1)
% focusList.length;
if (focusList[focusNumber].isEnabled() == false) {
getComponentBefore(focusCycleRoot, focusList[focusNumber]);
}
return focusList[focusNumber];
}
});
In my case nothing above worked untill I called requestFocus() AFTER my constructor has returned.
MyPanel panel = new MyPanel(...);
frame.add(panel);
panel.initFocus();
MyPanel.initFocus() would have:
myTextField.requestFocus();
And it works.
This code mouse cursor “jtextfield” “Jcombobox” location focused
try {
Robot robot = new Robot();
int x = Jtextfield.getLocationOnScreen().x;
int y= Jtextfield.getLocationOnScreen().y;
JOptionPane.showMessageDialog(null, x+"x< - y>"+y);// for I location see
robot.mouseMove(x, y);
} catch (AWTException ex) {
ex.printStackTrace();
}
It was not working for me when tried to use:
JOptionPane.showConfirmDialog(...)
But -
I found a solution !
Very primitive, but works.
Just jump to the field by java.awt.Robot using key "Tab".
For example:
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(100);
robot.keyRelease(KeyEvent.VK_TAB);
If you should press multiple times on "Tab" to get your Component you can use below method:
GUIUtils.pressTab(3);
Definition:
public static void pressTab(int amountOfClickes)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
Robot robot = new Robot();
int i = amountOfClickes;
while (i-- > 0)
{
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(100);
robot.keyRelease(KeyEvent.VK_TAB);
}
}
catch (AWTException e)
{
System.out.println("Failed to use Robot, got exception: " + e.getMessage());
}
}
});
}
If your Component location is dynamic, you can run over the while loop without limitation, but add some focus listener on the component, to stop the loop once arrived to it.
While yourTextField.requestFocus() is A solution, it is not the best since in the official Java documentation this is discourage as the method requestFocus() is platform dependent.
The documentation says:
Note that the use of this method is discouraged because its behavior is platform dependent. Instead we recommend the use of requestFocusInWindow().
Use yourJTextField.requestFocusInWindow() instead.
How about put jTextField.requestFocusInWindow(); into jTextField FocusLost event?
Works for me
have 5 controls on JPanel
Soon as click on MessageBox, focus lost on jTextField.
Used all the suggested codes but no luck
Only above method works my case.

JButton breaks my Keylistener

JAVA USING NETBEANS
Hello stackoverflow, i have a problem i would like help with. In a nutshell, I have a mouselistener and a keylistener on a jpanel, everything works fine except when i press one of my jbuttons, then the keylistener goes AWOL. Can any1 explain the problem, is the panels focus now on the buttons instead of the keyboard, im at a lost.
Here is the code, if somethings are not reference, assume its are there the entire panel code was 500+ long so i cut quite a bit.
Thanks in advance for any help.
package tankgame;
public class TankPanel extends JPanel implements KeyListener,
MouseListener,MouseMotionListener
{
JButton back,shop, menu, health, speed, rapidfire, shootradius;
TankPanel()
{
setLayout( null );
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
setFocusable(true);
shop= new JButton("SHOP");
shop.addMouseListener(this);
shop.setBounds(400,0, 80,15);
add(shop);
}
public void keyPressed(KeyEvent k)
{
char c = k.getKeyChar();
if(c=='u')
{
u++;
System.out.println(u+" = u");
}
if(c=='i')
{
i++;
System.out.println(i+" = i");
}
if( c == 'd' )
{
if(Ptank.pic==PlayerTankE)
{
if(Ptank.move==true)
{
Pbarrel.x+=Ptank.speed;
Ptank.x+=Ptank.speed;
}
}
else
{
if(Ptank.pic==PlayerTankN || Ptank.pic==PlayerTankS)
{
Ptank.x = Ptank.x - 5;
Ptank.y=Ptank.y+5;
}
Ptank.setPic(PlayerTankE);
Ptank.width=35;
Ptank.height = 23;
}
}
setFocusable(true);
repaint();
}
public void keyReleased(KeyEvent k)
{
}
public void keyTyped(KeyEvent k)
{
}
public void mouseClicked(MouseEvent e)
{
//Invoked when the mouse button has been clicked (pressed and released)
}
public void mouseEntered(MouseEvent e)
{//Invoked when the mouse enters a component.
}
public void mouseExited(MouseEvent e)
{ //Invoked when the mouse exits a component.
}
public void mousePressed(MouseEvent e)
{//Invoked when a mouse button has been pressed on a component.
if(e.getSource()==back)
{
System.out.println(456);
System.out.println(back.getLocation().x + " "+back.getLocation().y);
}
else if(e.getSource() == menu)
{
changebuttons("menu");
System.out.println(456);
System.out.println(menu.getLocation().x + " "+menu.getLocation().y);
}
else if(e.getSource() == shop)
{
changebuttons("shop");
System.out.println(456);
System.out.println(shop.getLocation().x + " "+shop.getLocation().y);
}
else if(e.getButton() == MouseEvent.BUTTON1)
{
destpoint= new Point();
destpoint.setLocation(mousex, mousey);
origin = new Point();
}
for(int i = 0; i< Ptank.rapidfire; i++)
{
if (origin.distance(destpoint) <= 100 && origin.distance(destpoint) >= 50)
{
Bullet add = new Bullet(this,destpoint);
add.getOrigin(origin);
add.setPic(PlayerBullet);
add.width=4;
add.height=4;
bulletList.add(add);
}
}
}
}
public void mouseReleased(MouseEvent e)
{//Invoked when a mouse button has been released on a component.
}
public void mouseDragged(MouseEvent e)
{//Invoked when a mouse button is pressed on a component and then dragged.
}
public void mouseMoved(MouseEvent e)
{
//Invoked when the mouse cursor has been moved onto a component but no buttons
Cursor cursor = Cursor.getDefaultCursor();
//you have a List<Polygon>, so you can use this enhanced for loop
cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
setCursor(cursor);
mousex=e.getX();
mousey=e.getY();
}
public void changebuttons(String x)
{
if(x.equals("shop"))
{
menu.setBounds(720, 0, 80, 15);
health.setBounds(0, 0, 125, 15);
speed.setBounds(150, 0, 125, 15);
shootradius.setBounds(300, 0, 200, 15);
rapidfire.setBounds(500, 0, 150, 15);
shop.setBounds(1000, 0, 150, 15);
}
}
KeyEvents are only generated on a component that has focus. When you click on the button is now has focus to key events won't be generated on the panel. You need to add:
panel.requestFocusInWindow()
in your ActionListener to give focus back to the panel.
However the better solution is to use Key Bindings as you can add bindings to a KeyStroke even when the component doesn't have focus.
Don't use a KeyListener which requires the component be focused to work. Instead consider using Key Bindings. You can find out how to use these guys at the Swing tutorial: How To Use Key Bindings. If you need more specific help, you will want to post a much smaller bit of code than you show above, code that is self-contained and will actually compile and run for us, an SSCCE.

Swing: how do I close a dialog when the ESC key is pressed?

GUI development with Swing.
I have a custom dialog for choosing a file to be opened in my application; its class extends javax.swing.JDialog and contains, among other components, a JFileChooser, which can be toggled to be shown or hidden.
The JFileChooser component already handles the ESC key by itself: when the file chooser is shown (embedded in my dialog) and I press ESC, the file chooser hides itself.
Now I would like my dialog to do the same: when I press ESC, I want the dialog to close. Mind you, when the embedded file chooser is shown, the ESC key should only hide it.
Any ideas ?
You can use the following snippet. This is better because the rootPane will get events from any component in the dialog. You can replace setVisible(false) with dispose() if you want.
public static void addEscapeListener(final JDialog dialog) {
ActionListener escListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
};
dialog.getRootPane().registerKeyboardAction(escListener,
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW);
}
Use InputMap and ActionMap for dealing with key actions in Swing. To close the dialog cleanly, send a window closing event to it.
From my now defunct weblog:
private static final KeyStroke escapeStroke =
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
public static final String dispatchWindowClosingActionMapKey =
"com.spodding.tackline.dispatch:WINDOW_CLOSING";
public static void installEscapeCloseOperation(final JDialog dialog) {
Action dispatchClosing = new AbstractAction() {
public void actionPerformed(ActionEvent event) {
dialog.dispatchEvent(new WindowEvent(
dialog, WindowEvent.WINDOW_CLOSING
));
}
};
JRootPane root = dialog.getRootPane();
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
escapeStroke, dispatchWindowClosingActionMapKey
);
root.getActionMap().put( dispatchWindowClosingActionMapKey, dispatchClosing
);
}
If your looking for a technique using new features of Java 8 , try a lambda expression:
dialog.getRootPane().registerKeyboardAction(e -> {
window.dispose();
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
or
KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
int w = JComponent.WHEN_IN_FOCUSED_WINDOW;
dialog.getRootPane().registerKeyboardAction(e -> window.dispose(), k, w);
I had problems implementing both of the top answers. Here's a rather compact version using AbstractAction to auto-implement most of Action's methods, which works within text-based fields (per #pratikabu's request):
final AbstractAction escapeAction = new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent ae) {
dispose();
}
};
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ESCAPE_KEY");
getRootPane().getActionMap().put("ESCAPE_KEY", escapeAction);
References
the above answers
http://www.coderanch.com/t/335357/GUI/java/KeyPressed-JDialog
Here's mine, I add CtrlW as closing shorcut aswell
Action closeAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
dispose();
}
};
KeyStroke esc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(esc, "closex");
getRootPane().getActionMap().put("closex", closeAction);
KeyStroke ctrlW = KeyStroke.getKeyStroke("control W");
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlW, "close");
getRootPane().getActionMap().put("close", closeAction);

Categories

Resources