Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6446890

Toolkit.getLockingKeyState fails to correctly report NUM LOCK status

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 1.4.2, 5.0
    • client-libs
    • Cause Known
    • x86
    • windows_xp

      FULL PRODUCT VERSION :
      java version "1.4.2_07"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_07-b05)
      Java HotSpot(TM) Client VM (build 1.4.2_07-b05, mixed mode)
      --------
      Also exists in:
      java version "1.5.0_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
      Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      getLockingKeyState fails to return the state of the Num Lock key correctly. The example code displays the Num Lock state in a label. The initial state is always detected correctly. It responds correctly to KeyEvents to detect the pressing of the Num Lock key. If focus is lost and then regained, it is supposed to check the state of the Num Lock key again. This call to getLockingKeyState always returns the last read value rather than the actual state of Num Lock.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the test case. Note that the initial reported state is correct and that toggling Num Lock whilst the Frame has focus also works correctly. Change the focus away from the frame. Toggle Num Lock. Change the focus back to the Frame. Note that the reported state is not updated. This is due to getLockingKeyState not returning the correct value.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The label should be updated with the new state of Num Lock.
      ACTUAL -
      The label stays showing the state that held true before the Frame lost focus.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class Test {
          private JLabel label = new JLabel("Num Lock State Displayed Here");

          private boolean numLockState;

          private Test() {
              numLockState = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK);
              updateLabelText();
              Toolkit.getDefaultToolkit().addAWTEventListener(new EventHandler(), AWTEvent.KEY_EVENT_MASK);
              KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusedWindow", new PropertyChangeHandler());
          }

          private void updateLabelText() {
              label.setText("Num Lock is " + (numLockState ? "On" : "Off"));
          }

          private void updateNumLockState() {
              boolean currentNumLockState = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK);
              if (currentNumLockState != numLockState) {
                  numLockState = currentNumLockState;
                  updateLabelText();
              }
          }


          public static void main(String[] args) {
              Test test = new Test();
              JFrame frame = new JFrame();
              frame.setSize(200, 200);
              frame.getContentPane().add(test.label);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setVisible(true);

          }

          private class EventHandler implements AWTEventListener {
              public void eventDispatched(AWTEvent event) {
                  if (event instanceof KeyEvent) {
                      KeyEvent keyEvent = (KeyEvent) event;
                      if (keyEvent.getID() == KeyEvent.KEY_PRESSED && keyEvent.getKeyCode() == KeyEvent.VK_NUM_LOCK) {
                          updateNumLockState();
                      }
                  }
              }
          }

          private class PropertyChangeHandler implements PropertyChangeListener {
              public void propertyChange(PropertyChangeEvent evt) {
                  if (evt.getOldValue() == null && evt.getNewValue() != null) {
                      updateNumLockState();
                  }
              }
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      This is not so much a workaround as more info that might help. I discovered that any key press on the keyboard after the focus has been regained will mean that getLockingKeyState will return the right value thereafter. As a workaround, I tried to use java.awt.Robot.keyPress to simulate a key press and then query the state of Num Lock, but discovered that this will not work if you switch the focus back by clicking on the title bar of the frame. If you click inside the frame or click on the button on the start bar to change the focus, then this workaround will work. Since it doesn't work in all cases though it can't be considered a real workaround. It also might indicate both part of the cause of the bug and/or another potential bug in the GUI framework.

            yan Yuri Nesterenko
            dav Andrei Dmitriev (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: