United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-5087251 AWT Button triggers ActionEvent even though all the key events are retargetted
JDK-5087251 : AWT Button triggers ActionEvent even though all the key events are retargetted

Details
Type:
Bug
Submit Date:
2004-08-16
Status:
Closed
Updated Date:
2005-12-01
Project Name:
JDK
Resolved Date:
2005-07-23
Component:
client-libs
OS:
windows_xp
Sub-Component:
java.awt
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Relates:
Relates:
Relates:

Sub Tasks

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
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mustang


                                     
2004-08-18
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
                                     
2005-06-19
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
                                     
2005-07-11



Hardware and Software, Engineered to Work Together