Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4531849
Votes 1
Synopsis REG: Extra ActionEvent fired on win32
Category java:classes_awt
Reported Against merlin-rc1
Release Fixed 1.4.2(mantis)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 4327679 , 4530087 , 4531852 , 5044469
Submit Date 27-NOV-2001
Description
Pressing mouse buttons in a certain way on java.awt.Buttons can cause two ActionEvents to be fired, instead of just one.  Consider this simple test case:

// Test of double ActionEvents

import java.awt.*;
import java.awt.event.*;

public class ActionTest extends Frame implements ActionListener {
    Button b;

    public ActionTest() {
        super("ActionTest");
        b = new Button("Action Listening Button");
        b.addActionListener(this);
        add(b);
        setSize(200, 200);
    }

    static int i = 0;
    public void actionPerformed(ActionEvent e) {        
        System.out.println("actionPerformed() called - " + (i++));
    }

    public static void main(String[] args) {
        ActionTest at = new ActionTest();
        at.show();
    }
}

---
Press both the left and right mouse buttons while over the Action Listening Button.  Next, release the left mouse button.  You will see that actionPerformed() is called twice.  This is a regression since 1.3.1, and does not happen on Solaris.  See also bug 4530087.
Work Around
N/A
Evaluation
Regression - commit to hopper.
  xxxxx@xxxxx   2001-11-27

Here is another test case which fires two action events when a Window is Activated with a Button press:

import java.awt.*;
import java.awt.event.*;

public class ButtonActionEventTest extends Frame
    implements ActionListener
{
    int actionCount = 0;
    public ButtonActionEventTest() {
        super("button ActionEvent test");
        Button b = new Button("Press Me");
        b.addActionListener(this);
        b.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent me) {
                    System.out.println("mouseClicked");
                }
                public void mousePressed(MouseEvent me) {
                    System.out.println("mousePressed");
                }
                public void mouseReleased(MouseEvent me) {
                    System.out.println("mouseReleased");
                }
            });
        add(b);
        addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent we) {
                    ButtonActionEventTest.this.dispose();
                    System.exit(0);
                }
                public void windowActivated(WindowEvent we) {
                    //System.out.println(we);
                    try {
                        System.out.println(we);
                        Thread.sleep(1000);
                    } catch (InterruptedException ie) {
                    }                    
                }
            });
        pack();
        setVisible(true);
    }

    public void actionPerformed(ActionEvent ae) {
        System.out.println("action performed " + actionCount++);
    }

    public static void main(String[] args) {
        new ButtonActionEventTest();
    }
}

I did notice that without the sleep(), the problem disappears.  Timing issue?

  xxxxx@xxxxx   2001-11-28

The cause of this bug is the fix for 4327679, which was putback with fixes for similar bugs 4327618, 4327623, 4327639, 4327654, 4327664, 4327676.  This could be confirmed by running the test cases with Merlin builds 30 and 31 - it would be introduced in b31.
     
MOUSE_DRAGGED and MOUSE_RELEASED events were fixed by capturing the mouse on all
button presses.  Several regressions were found and fixed before the putback,
but this one was missed.

Before the mouse capturing, ActionEvents were sent to Buttons in response to
WM_COMMAND messages (via WmNotify()).  This covered the case of mouse clicks as well as pressing the space bar.  The MSDN docs for SetCapture() state, "When the mouse is captured, menu hotkeys and other keyboard accelerators do not work."  This is true in that when we capture the mouse, no WM_COMMAND message are received.

With mouse capturing, space bar still sent WM_COMMAND messages, but mouse clicks didn't, so WM_LBUTTONUP handling was changed to also call WmNotify(), sending ActionEvents as appropriate.

This bug is due in part to bugs/underspecification in the Win32 APIs.  Clearly,
there is some relationship between WM_COMMAND events and mouse capture, but it
is not well specified.

It appears that Windows treats left and right mouse buttons differently with respect to capture.  Using Spy++, I observed that clicking on a Button w/ the left mouse button results in two WM_CAPTURECHANGED events.  But w/ the right mouse button, we see a WM_CAPTURECHANGED only on the release.  If both buttons are held down and only the left button is  released, we appear to lose mouse capture (we see a WM_CAPTURECHANGED event) though we don't call ReleaseCapture(), and the attempt to release capture on the right button release fails because we don't have capture.  It is these capture-related behaviors of Windows that cause our problems. For some reason, Windows sees fit to release our mouse capture AND send a WM_COMMAND message if we left click on a Button while the right mouse button is also down.  This is where our two ActionEvents come from: one through WmMouseUp->WmNotify(), and one through WmCommand()->WmNotify().
  
There a couple possible solutions, which I'm now investigating.
  xxxxx@xxxxx   2002-08-26
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang