JDK-5087251 : AWT Button triggers ActionEvent even though all the key events are retargetted
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-08-16
  • Updated: 2005-12-01
  • Resolved: 2005-07-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b45Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
I am showing a frame with a button. I have implemented a KeyEventDispatcher which would consume all the key events triggered by the button and it's dispatchKeyEvent() method returns true to prevent further processing of those events by the KeyboardFocusManager. But when I press space bar, the button responds by triggering an action event on Win32. But the button is not getting visually pressed.

This is reproducible on WinXP since JDK1.4+. This is not reproducible on Solaris / Linux where the button does not trigger any action event when the space bar is pressed.  I tried the same with JButton on WinXP and this issue does not occur with Swing button.

The button should not trigger action event when space bar is pressed. But if that is a native behavior, at least it should respond visually to show the user that it is pressed.

I have attached a sample test. Execute the sample test. You would see a frame with a JButton and a Button. Make sure the focus is in AWT button. Press the space bar. If the console shows 'Button Clicked' message, the bug is reproduced.

Comments
EVALUATION Name: at153223 Date: 08/17/2004 The problem is that AWT native behaviour is different on Windows and Solaris/Linux. Activating a button on Solaris/Linux looks like the following: 1. got native 'KeyPress' - posting KEY_PRESSED to Java (from event handler) 2. got Java KEY_PRESSED - dispatching it to native widget 3. native 'activateCallback' function is triggered - posting ACTION_PERFORMED to Java (from the callback) 4. and so on... And here's what tooks place on Windows: 1. got WM_KEYDOWN - processing... - posting KEY_PRESSED & KEY_TYPED to Java 2. got WM_KEYUP - posting ACTION_PERFORMED to Java (from WmKeyUp callback) - posting KEY_RELEASED to Java As you see on Windows posting ACTION_PERFORMED happens before an appropriate key event is processed in Java. On Solaris/Linux, quite the contrary, ACTION_PERFORMED is posting after the key event was appropriately processed in Java. That's why retargetting key event on Windows doesn't prevent ACTION_PERFORMED from being posted. ###@###.### 08/17/2004 ====================================================================== ###@###.### 10/6/04 14:50 GMT When we release keyboard key in native code arrives WM_KEYUP message. After it our native code generates and posts ActionEvent and at the same time posts KeyEvent.KEY_RELEASED event. During dispatching of the KeyEvent user or someAWT code can consume the event (user could make its own KeyEventDispatcher, KeyEvent.KEY_TYPED will be consumed if in an application shortcut exists). As we send ActionEvent and KeyEvent at the same time it is not possible to consume ActionEvent if KeyEvent was consumed. The solution is to move sending of ActionEvent in a place there we definitely know that KeyEvent was not consumed. ###@###.### 2005-07-11 04:48:17 GMT
11-07-2005

SUGGESTED FIX We should override handleEvent method in WButtonPeer to handle KeyEvent.KEY_RELEASED event in an appropriate way. This method is invoked from shared code (Component.dispatchEventImpl()) when we really know that KeyEvent was not consumed. *** src/windows/native/sun/windows/awt_Button.cpp- Sun Jun 19 18:55:48 2005 --- src/windows/native/sun/windows/awt_Button.cpp Sun Jun 19 18:55:48 2005 *************** *** 194,202 **** AwtButton::WmKeyUp(UINT wkey, UINT repCnt, UINT flags, BOOL system) { MsgRouting mrResult = AwtComponent::WmKeyUp(wkey, repCnt, flags, system); - if (!system && wkey == VK_SPACE) { - NotifyListeners(); - } return mrResult; } --- 194,199 ---- *** src/windows/classes/sun/awt/windows/WButtonPeer.java- Sun Jun 19 18:55:48 2005 --- src/windows/classes/sun/awt/windows/WButtonPeer.java Sun Jun 19 18:55:48 2005 *************** *** 9,14 **** --- 9,15 ---- import java.awt.*; import java.awt.peer.*; import java.awt.event.ActionEvent; + import java.awt.event.KeyEvent; class WButtonPeer extends WComponentPeer implements ButtonPeer { *************** *** 74,77 **** --- 75,89 ---- */ private static native void initIDs(); + public void handleEvent(AWTEvent e) { + int id = e.getID(); + switch (id) { + case KeyEvent.KEY_RELEASED: + KeyEvent ke = (KeyEvent)e; + if (ke.getKeyCode() == KeyEvent.VK_SPACE){ + handleAction(ke.getWhen(), ke.getModifiers()); + } + break; + } + } } ###@###.### 2005-06-19 15:02:34 GMT
19-06-2005

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang
18-08-2004