Java KeyListener: How to perform an action when two keys are pressed?
-
11-12-2019 - |
Question
Please have a look at the following code
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class KeyCheck extends JFrame
{
private JButton check;
private JPanel panel;
private FlowLayout flow;
public KeyCheck()
{
check = new JButton("Check");
check.addKeyListener(new KeyWork());
panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(check);
getContentPane().add(panel);
}
private class KeyWork extends KeyAdapter
{
public void keyPressed(KeyEvent k)
{
if(k.getKeyCode()==KeyEvent.VK_CONTROL && KeyEvent.VK_A)
{
JOptionPane.showMessageDialog(null, "OK");
}
}
}
public static void main(String[]args)
{
KeyCheck k = new KeyCheck();
k.setVisible(true);
k.setSize(200,200);
k.validate();
k.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
In this case, I have added an keylister to the button and I need to it to display the Message "OK" when CTRL + A is pressed together (control key and "A" key). But the above code is wrong. So, please help me to get message when both the keys are pressed together.
Solution
You are mixing key code and modifiers:
if(k.getKeyCode()==KeyEvent.VK_A
&& (k.getModifiers & KeyEvent.CTRL_MASK==KeyEvent.CTRL_MASK))
But more generally, it is better to use KeyBindings instead of KeyListener. It will make your life a lot easier and avoid you to have to make those kind of tests.
1.Create an Action like this:
public class MyAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "OK");
}
}
2.Bind the action to the key stroke:
check.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK), "doSomething");
check.getActionMap().put("doSomething", new MyAction());
Caveats: I haven't tested this code so may have to fix minor glitches.
OTHER TIPS
You should use methods in event k
:
if(k.isControlDown() && k.getKeyCode() == KeyEvent.VK_A) {
but remember that this will only work when your button is focused. For example when you add JTextField
to your frame
and write something in it - Ctrl+A
won't work because JTextField
is focused.
public void keyPressed(KeyEvent k)
{
if(k.getKeyCode() == KeyEvent.VK_A && (k.getModifiers & KeyEvent.CTRL_MASK) != 0)
{
JOptionPane.showMessageDialog(null, "OK");
}
}
}
You can also use key mnemonics or accelerators which is quite simple: 1. Mnemonics will open a menu 2. Accelerators will pressed the respective menu button
JMenuItem combination = new JMenuItem("Save File");
combination.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
combination.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == find) {
System.out.println("Ctrl+S pressed");
savefile();//depending on what your saving code is
}
}
});