JDK-4650902 : REGRESSION: Applets do not receive VK_TAB events in keyPressed.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.0,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_98,windows_xp
  • CPU: x86
  • Submitted: 2002-03-11
  • Updated: 2002-06-24
  • Resolved: 2002-06-24
Related Reports
Duplicate :  
Description

Name: gm110360			Date: 03/11/2002


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


FULL OPERATING SYSTEM VERSION :
Windows 98 [Version 4.10.2222]

A DESCRIPTION OF THE PROBLEM :
With the Java 2 Plug-in, a Java applet does not receive
java.awt.event.KeyEvent.VK_TAB events in the
keyPressed(KeyEvent e) method, despite the fact that the
applet has the keyboard focus.  All other keyboard events
appear to be passed in properly -- there may be other
exceptions, but I have not found any.

This behavior is inconsistent with the Netscape Navigator
implementation of applets, and also inconsistent with the
behavior of applets when they are run in Internet Explorer
under Microsoft's VM for Java.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Code a simple applet with a keyPressed(KeyEvent e)
method.
2. In the keyPressed(KeyEvent e) method, log all events
received, by printing them to the Java console with a
  statement like:
  System.out.println("keyPressed: " + e);
3. Issue calls to requestFocus() as necessary (according to
the design of the applet).
4. Code an HTML Web page that invokes the applet and install
the Web page and applet on a Web server.
5. Access the Web page from a browser, with the Java console
enabled.
6. Ensure the applet has the keyboard focus, by clicking the
mouse on the applet's window "box" on the Web page.
7. Press various keys on the keyboard and observe the
results in the Java console.  Observe that the "Tab" key
produces no message in the Java console, but all other keys
are logged.
8. Try the same experiment without the Java 2 Plug-in, using
the Java support shipped with Netscape Navigator or the
Microsoft version of Java for Internet Explorer.  Observe
that the "Tab" is logged in the Java console in these cases.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: Whenever you press the "Tab" key on the keyboard,
the keyPressed(KeyEvent e) method should be called with an
event "e" with e.getKeyCode() set to the value
java.awt.event.KeyEvent.VK_TAB.

Actual: The keyPressed(KeyEvent e) method receives no call
at all when the "Tab" key is pressed.

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.applet.Applet;
import java.awt.event.*;
import java.awt.Graphics;

public class keytest extends Applet implements KeyListener
  {
  public void init()
    {
    this.addKeyListener(this);
    }

  public void start()
    {
    requestFocus();
    }

  public void stop()
    {
    }

  public void paint(Graphics g)
    {
    //Draw a Rectangle around the applet's display area.
    g.drawRect(0, 0, getSize().width - 1, getSize().height - 1);
    }

  public void keyPressed(KeyEvent e)
    {
    System.out.println("keyPressed: " + e);
    }

  public void keyTyped(KeyEvent e)
    {
    System.out.println("keyTyped: " + e);
    }

  public void keyReleased(KeyEvent e)
    {
    System.out.println("keyReleased: " + e);
    }
  }

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

Release Regression From : 1.3.1_02
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Review ID: 143957) 
======================================================================

Comments
EVALUATION I was able to reproduce the same problem in appletviewer - using keytest example attached to this bug. Reproducible on Windows and Solaris. I was also able to reproduce this with application (also on both - windows and solaris): import java.awt.event.*; import java.awt.Graphics; import java.awt.*; public class keytestframe extends Frame implements KeyListener { public void init() { this.addKeyListener(this); } public void start() { requestFocus(); this.setVisible(true); } public void stop() { } public void paint(Graphics g) { //Draw a Rectangle around the applet's display area. g.drawRect(0, 0, getSize().width - 1, getSize().height - 1); } public void keyPressed(KeyEvent e) { System.out.println("keyPressed: " + e); } public void keyTyped(KeyEvent e) { System.out.println("keyTyped: " + e); } public void keyReleased(KeyEvent e) { System.out.println("keyReleased: " + e); } public static void main (String [] args){ keytestframe kt = new keytestframe(); kt.setTitle("Test key"); kt.setSize(250, 150); kt.init(); kt.start(); } } Re-assigning this bug to classes_awt team. ###@###.### 2002-05-15 I suspect this was done on purpose as part of the focus rearchitecture in 1.4: http://webwork.sfbay.sun.com/j2se/1.4/docs/api/java/awt/doc-files/FocusSpec.html#Incompatibilities ###@###.### 2002-05-15 Name: osR10079 Date: 06/24/2002 This imcompatibility with previous version is described by the new Focus API specification (located in doc/api/java/awt/doc-files/FocusSpec.html) in "Incompatibilities with Previous Releases" section. Here is a quote: > KeyListeners installed on Components will no longer see KeyEvents > that map to focus traversal operations. Previously, AWT Components > saw these events and had an opportunity to consume them before the > AWT initiated focus traversal. Code that requires this functionality > should instead disable focus traversal keys on its Components and > handle focus traversal itself. Alternately, the code can use an > AWTEventListener or KeyEventDispatcher to pre-listen to all KeyEvents. Thus this is not a bug. ###@###.### Jun 24, 2002 ======================================================================
24-08-2004

WORK AROUND As part of the new focus architecture introduced in 1.4.0, focus traversal keys (in most cases this means the <code>TAB</code> key) are now consumed, which can cause problems if a program depends on a key listener being notified of these key events. To avoid focus traversal keys being consumed, use the following code: component.setFocusTraversalKeysEnabled(false); where <code>component</code> is the <code>Component</code> that is firing the key events. ###@###.### 2002-12-13 Name: osR10079 Date: 03/20/2003 Here is a small example how call Component.setFocusTraversalKeysEnabled(boolean) using reflection: import java.awt.Component; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; public class wa4650902 { public static void main(String[] args) { Component comp = new Component() {}; if (System.getProperty("java.version").startsWith("1.4")) { System.out.println("before " + comp.getFocusTraversalKeysEnabled()); try { Method method = Component.class.getMethod("setFocusTraversalKeysEnabled", new Class[]{Boolean.TYPE}); method.invoke(comp, new Object[] {Boolean.FALSE}); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } System.out.println("after " + comp.getFocusTraversalKeysEnabled()); } else { // do nothing System.out.println(System.getProperty("java.version")); } } } Note: this example should be compiled by 1.4 or later (because of direct calls to Component.getFocusTraversalKeysEnabled() in the println statements), but can be run with any earlier verions of the jdk. If you want to be able to compile it with earlier version of jdk too, then either remove these calls from the printlns, or make them using reflection. ###@###.###, March 20 2003 ======================================================================
24-08-2004