Question

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!

Was it helpful?

Solution

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( );

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top