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

FocusManager consumes wrong KEYTYPED-Events

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 5.0
    • 1.4.1, 5.0
    • client-libs
    • tiger
    • x86
    • windows_2000



      Name: jk109818 Date: 11/21/2002


      FULL PRODUCT VERSION :
      java version "1.4.1_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-
      b01)
      Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

      FULL OPERATING SYSTEM VERSION :Microsoft Windows 2000 [Version
      5.00.2195]


      A DESCRIPTION OF THE PROBLEM :
      The java.awt.DefaultKeyboardManager consumes KEYTYPED-Events for
      handled FocusTraversalKeys-KEYPRESSED-Events. If one sets an ActionKey
      as FocusTraversalKey (eg. LEFT or RIGHT) DefaultKeyboardManager will
      do so regardlessly ActionKeys don't produce KEYTYPED-Events. Hence the
      following KEYTYPED-Event will be consumed. If one traverses into a
      JTextArea the first typed Key will be lost.
      TAB-Key will not cause this
      since it produces a KEYTYPED-Event.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      A simple program will demonstrate the effect.
      Traverse with DOWN into
      the JTextArea and the first typed character will be lost.



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      First character typed into JTextArea ist lost. This ist caused by
      DefaultKeyboardManager's processKeyEvent-method:

          public void
      processKeyEvent(Component focusedComponent, KeyEvent e) {
      //
      KEY_TYPED events cannot be focus traversal keys
      if (e.getID() ==
      KeyEvent.KEY_TYPED) {
      if (consumeNextKeyTyped)
      {
      e.consume();
      consumeNextKeyTyped = false;
      }


      return;
      }

              if
      (focusedComponent.getFocusTraversalKeysEnabled() &&
                  
      !e.isConsumed())
              {
      AWTKeyStroke stroke =
      AWTKeyStroke.getAWTKeyStrokeForEvent(e),
      oppStroke =
      AWTKeyStroke.getAWTKeyStroke(stroke.getKeyCode(),

      stroke.getModifiers(),
      !stroke.isOnKeyRelease());
      Set
      toTest;
      boolean contains, containsOpp;

      toTest =
      focusedComponent.getFocusTraversalKeys(
                      
      KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
      contains =
      toTest.contains(stroke);
      containsOpp =
      toTest.contains(oppStroke);

      if (contains || containsOpp)
      {
      if (contains) {

      focusNextComponent(focusedComponent);
      }
      e.consume();
      consumeNextKeyTyped
      = (e.getID() == KeyEvent.KEY_PRESSED);
      return;

      }
      [...]
      }

      The condition for 'consumeNextKeyTyped' should
      be
      "consumeNextKeyTyped = ((e.getID() == KeyEvent.KEY_PRESSED)) &&
      !e.isActionKey();"
      instead.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import java.awt.*;
      import java.awt.event.KeyEvent;
      import java.util.Set;
      import java.util.HashSet;

      class FocusTest extends JFrame {

          public FocusTest() {
              setDefaultCloseOperation(EXIT_ON_CLOSE);
              Container contentPane = getContentPane();
              Set ftk = new HashSet();
              ftk.add(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0));
              ftk.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
              
      contentPane.setFocusTraversalKeys(
      KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,ftk);
              Set btk = new HashSet();
              btk.add(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0));
              btk.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
      KeyEvent.SHIFT_DOWN_MASK));
              contentPane.setFocusTraversalKeys(
                   KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,btk);
              contentPane.setLayout(new BoxLayout(contentPane,BoxLayout.Y_AXIS));
              JCheckBox cba = new JCheckBox("test1");
              
      contentPane.add(cba);
              JTextArea jta = new JTextArea(40, 10);
              contentPane.add(jta);
              
      pack();
              setVisible(true);
          }

      public static void main(String args[]){

      FocusTest test = new FocusTest();

      }

      }
      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Use an extended DefaultFocusManager where you've overwritten
      'processKeyEvent' to not try to consume KEYTYPED-Events from
      ActionKeys.
      (Review ID: 167245)
      ======================================================================

            son Oleg Sukhodolsky (Inactive)
            jkimsunw Jeffrey Kim (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: