I use the following code to create hot keys for the java form using swing. If I press ALT+N,ALT+R,ALT+1,ALT+2 the cursor moves to correct text fields and I enter the value i
You need to register a keyBinding in the button's component inputmap. In code (repeating a subtle variant of what you have been told to do in your previous questions :-)
// create an Action doing what you want
Action action = new AbstractAction("doSomething") {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("triggered the action");
}
};
// configure the Action with the accelerator (aka: short cut)
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control S"));
// create a button, configured with the Action
JButton toolBarButton = new JButton(action);
// manually register the accelerator in the button's component input map
toolBarButton.getActionMap().put("myAction", action);
toolBarButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
(KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "myAction");
Sun has a really good Description of the whole Key Binding issue. You can find it here:
JavaSE Tutorial on Keybinding
//EDIT
Edited my example code so you can just copy + paste it and it will work. Included the points that were missing, thanks for the feedback.
KeyStroke keySave = KeyStroke.getKeyStroke(KeyEvent.VK_S, Event.CTRL_MASK);
Action performSave = new AbstractAction("Save") {
public void actionPerformed(ActionEvent e) {
//do your save
System.out.println("save");
}
};
JButton b1 = new JButton(performSave);
b1.getActionMap().put("performSave", performSave);
b1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keySave, "performSave");
KeyStroke keyExit = KeyStroke.getKeyStroke(KeyEvent.VK_Y, Event.CTRL_MASK);
Action performExit = new AbstractAction("Exit") {
public void actionPerformed(ActionEvent e) {
//exit
System.out.println("exit");
}
};
JButton b2 = new JButton(performExit);
b2.getActionMap().put("performExit", performExit);
b2.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyExit, "performExit");
I provide this as much for me as a learning experience as for anyone else. I've always had difficulty applying code snippets for key binding that I've found in the past and I hope my explanation and code will be clear. Thanks to @kleopatra for her code snippet, on which I base my code below.
(I'm using CAPITAL LETTERS where I should NOT in order to more clearly show what MUST MATCH.)
The code links the Ctrl-Shift-U
keystroke to the code in actionPerformed
for MYACTION
via the matching strings in getInputMap
and getActionMap
.
The three instances of MYACTION
below must match, as must the four instances of MYACTIONBUTTON
, as must the two instances of the string MAKE_THESE_MATCH
. Call them what you will; just make them match.
The button MYACTIONBUTTON
must have MYACTION
as the argument to the JButton
defining it AND must have getInputMap
and getActionMap
applied to it.
private static JButton MYACTIONBUTTON;
private static JFrame frame;
private static JPanel panel;
...
Action MYACTION = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
// put action code here
}
};
MYACTIONBUTTON = new JButton(MYACTION);
MYACTIONBUTTON.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(getKeyStroke(VK_U, CTRL_DOWN_MASK | SHIFT_DOWN_MASK),
"MAKE_THESE_MATCH");
MYACTIONBUTTON.getActionMap().put("MAKE_THESE_MATCH", MYACTION);
panel.add(MYACTIONBUTTON);
frame.add(panel);
Just modified your code. (inserted code in //**)
Just 1 comment... Ctrl-X is shortcut for edit command "Cut" (along with Ctrl-C & Ctrl-V). You have editable fields in frame. I used Ctrl-Q (quit) instead.
import java.awt.event.*;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.plaf.ActionMapUIResource;
import java.net.*;
public class HotKeys extends JFrame {
public static void main(String arg[]) {
JLabel Name = new JLabel("Name");
JTextField tf1 = new JTextField(20);
Name.setLabelFor(tf1);
Name.setDisplayedMnemonic('N');
JLabel Regno = new JLabel("RegNO");
JTextField tf2 = new JTextField(20);
Regno.setLabelFor(tf2);
Regno.setDisplayedMnemonic('R');
JLabel Mark1 = new JLabel("Mark1");
JTextField tf3 = new JTextField(20);
Mark1.setLabelFor(tf3);
Mark1.setDisplayedMnemonic('1');
JLabel Mark2 = new JLabel("Mark2");
JTextField tf4 = new JTextField(20);
Mark2.setLabelFor(tf4);
Mark2.setDisplayedMnemonic('2');
JButton b1 = new JButton("Save");
JButton b2 = new JButton("eXit");
JFrame f = new JFrame();
JPanel p = new JPanel();
p.add(Name);
p.add(tf1);
p.add(Regno);
p.add(tf2);
p.add(Mark1);
p.add(tf3);
p.add(Mark2);
p.add(tf4);
p.add(b1);
p.add(b2);
// *****************************************************
ActionMap actionMap = new ActionMapUIResource();
actionMap.put("action_save", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Save action performed.");
}
});
actionMap.put("action_exit", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Exit action performed.");
}
});
InputMap keyMap = new ComponentInputMap(p);
keyMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S,
java.awt.Event.CTRL_MASK), "action_save");
keyMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q,
java.awt.Event.CTRL_MASK), "action_exit");
SwingUtilities.replaceUIActionMap(p, actionMap);
SwingUtilities.replaceUIInputMap(p, JComponent.WHEN_IN_FOCUSED_WINDOW,
keyMap);
// *****************************************************
f.add(p);
f.setVisible(true);
f.pack();
}
}