Check whether shift key is pressed

11k Views Asked by At

I'm programming an application which should, when started, check whether the shift key is pressed. For that I have created a small class which is responsible for that:

import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;

public class KeyboardListener {

    private static boolean isShiftDown;

    static {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
            new KeyEventDispatcher() {
                public boolean dispatchKeyEvent(KeyEvent e) {
                    isShiftDown = e.isShiftDown();
                    return false;
                }
            });
    }

    public static boolean isShiftDown() {
        return isShiftDown;
    }

}

However, it seems that this is not working if the shift key was already pressed when the application started up. The following check always executes the else case.

if (KeyboardListener.isShiftDown()) {
    // ...
} else {
    // this always gets executed
}

Is there a way of checking whether the shift key is pressed if it was already pressed when the application started? I know this is possible using WinAPI, but I would prefer a Javaish way of doing it.

Thanks in advance!

5

There are 5 best solutions below

0
ulmangt On BEST ANSWER

I'd characterize this as a hack, but it does solve the problem (with some downsides), so I figured I would mention it as a possibility.

You can use the Robot class to simulate a keystroke of some key that your application doesn't care about (perhaps one of the function keys). Run this code right after you register your KeyListener. You'll see a key event which will tell you whether Shift is down.

Warning: This will appear to the system as if the F24 (or whatever key you choose) had actually been pressed and released by the user. That could potentially have unexpected side-effects.

    (new Thread( )
    {
        @Override
        public void run( )
        {
            try
            {
                java.awt.Robot robot = new Robot();
                robot.delay( 100 );
                robot.keyPress( KeyEvent.VK_F24 );
                robot.keyRelease( KeyEvent.VK_F24 );
            }
            catch ( Exception e )
            {
            }
        }
    }).start( );
0
Jan Henke On

It does not seem possible, since it requires the application to poll for the initial status, opposed to the model of events used by AWT/Swing.

2
awiebe On

Cleaning up your coding style might help, I find your code difficult to read.

Your program probably doesn't listen to a shift that occured before the program started by design, as this shift was sent to the parent program not to it.

0
MiguelMunoz On

I think you can do this by writing an AWTEventListener and listening for a key event when the shift key is pressed. You would need to install into the ToolKit:

Toolkit.getDefaultToolkit().addAWTEventListener(myShiftListener);

I'm not sure if it would work if you typed the key before launching the application. If you installed the KeyListener as your first operation, then it would be more likely to work if the key was typed after launching, but before the main window opened. That way, your code to build and show the main window could read the event. (You may have to put a small delay in after installing the listener.)

0
azis.mrazish On

The correct way is platform dependent, on windows you can use jna and call system key state API