0

I was wondering how to get all of the keys pressed in a key event. For example, I want to write a listener for ctrl + f that would toggle fullscreen. How could I check if both ctrl and f are pressed in one event?


EDIT 1:

I tried printing KeyEvent.getModifiersExText(e.getModifiersEx()) and typing ctrl + f, but that just yielded ?.

nrubin29
  • 1,522
  • 5
  • 25
  • 53

4 Answers4

3

To be honest, KeyListener has many limitations and is cumbersome to use (IMHO), instead, I would simply take advantage of the key bindings API, which generally provides you with a greater deal of flexibility and potentional for resuse.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class KeyListenerTest {

    public static void main(String[] args) {
        new KeyListenerTest();
    }

    public KeyListenerTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel lbl;
        private boolean fullScreen = false;

        public TestPane() {
            lbl = new JLabel("Normal");
            setLayout(new GridBagLayout());
            add(lbl);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK), "FullScreen");
            am.put("FullScreen", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (fullScreen) {
                        lbl.setText("Normal");
                    } else {
                        lbl.setText("Full Screen");
                    }
                    fullScreen = !fullScreen;
                }
            });

        }

    }

}

And just so you don't think I'm completely bias, here's an example using KeyListener...

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class KeyListenerTest {

    public static void main(String[] args) {
        new KeyListenerTest();
    }

    public KeyListenerTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel lbl;
        private boolean fullScreen = false;

        public TestPane() {
            lbl = new JLabel("Normal");
            setLayout(new GridBagLayout());
            add(lbl);

            setFocusable(true);
            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    requestFocusInWindow();
                }

            });

            addKeyListener(new KeyAdapter() {

                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_F && e.isControlDown()) {
                        if (fullScreen) {
                            lbl.setText("Normal");
                        } else {
                            lbl.setText("Full Screen");
                        }
                        fullScreen = !fullScreen;
                    }
                }

            });
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
2

Something like this should do it:

public MyListener extends KeyListener {
    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_DOWN_MASK) != 0)) {
            System.out.println("Keys ctrl+F pressed!");
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
});
quazzieclodo
  • 831
  • 4
  • 10
0

If you press two keys the 'keyPressed(KeyEvent e)' is called twice. You can store the pressed key in a boolean array and check if they are both pressed.

private boolean control_pressed = false;

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
      control_pressed = true;
    }

    if (e.getKeyCode() == KeyEvent.VK_F && control_pressed) {
        /* do something */
    }
}

public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
      control_pressed = false;
    }
}

The release has to release the control variable again.

Montaldo
  • 863
  • 8
  • 16
  • I hope you're going to correct that code...The `KeyEvent` also carries the modified state of the keystroke with it (ie, if CTRL, ALT, SHIFT or META keys are pressed as well), so you don't need to maintain to flag. This would then require you to provide a `keyReleased` implementation so you could reset the flag... – MadProgrammer Nov 06 '13 at 22:20
  • I kinda implied that with the sentence under there. Edited for the sake of completeness :). I like @quazzieclodo more tho, didn't think of that. – Montaldo Nov 06 '13 at 22:42
  • FYI `e.getKeyCode() = KeyEvent.VK_CONTROL` is not a valid comparison ;) – MadProgrammer Nov 06 '13 at 22:42
  • eeeeh my bad :(, anything else :D – Montaldo Nov 06 '13 at 22:47
  • No, that was the one that was freaking me out ;) – MadProgrammer Nov 06 '13 at 22:57
0

I found a few cool methods that will work in this instance:

e.isAltDown();

e.isAltGraphDown()

e.isControlDown()

e.isShiftDown()

nrubin29
  • 1,522
  • 5
  • 25
  • 53