2

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!

haiyyu
  • 2,194
  • 6
  • 22
  • 34

4 Answers4

1

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.

Jan Henke
  • 875
  • 1
  • 15
  • 28
1

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.

awiebe
  • 3,758
  • 4
  • 22
  • 33
  • I'm sorry, this is my first Java program that uses a GUI framework. What could I do to make my code more readable? – haiyyu Apr 08 '12 at 16:53
  • Basically you do too many operations in one line, use more variables and fewer anonymous entities. Remember code is for people to read not computers, your optomizing compiler will mostly be able to take care of making it run efficiently. – awiebe Apr 08 '12 at 18:02
1

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( );
ulmangt
  • 5,343
  • 3
  • 23
  • 36
0

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.)

MiguelMunoz
  • 4,548
  • 3
  • 34
  • 51