Name: chT40241 Date: 11/25/97
Mouse released events are not being generated sometimes when the mouse button is pressed, dragged, and
released quickly while exiting the component.
This bug causes a bad problem with components we have written such as
push buttons, toggle buttons, etc. This problem also occurs in HOTJAVA. If you press the mouse button while over one of the
buttons at the top of HotJava and drag and release quickly
as described above, the button will continue to think that the
mouse is pressed and will depress when the mouse enters it
even though the mouse isn't pressed.
Finally, the bug causes a problem with our implementation of
drag and drop within a Java application. When incorrect
events are generated, it acts incorrectly also.
Even though this bug doesn't sound important, it is. It is really
easy to trigger when clicking on a push button to start a drag
and drop session because people (unconsciously) perform the act of pressing the button and dragging very quickly.
*** test.java ***
import java.awt.*;
import java.awt.event.*;
// Move the mouse into the black square. Press
// the mouse button and quickly exit the square while
// releasing the mouse button. If you perform this quickly
// enough, the only events generated are MOUSE_PRESSED and
// MOUSE_EXITED. Without a MOUSE_RELEASED event, a component
// that expects correct mouse behavior will behave incorrectly.
// Also, AWT will sometimes generate the enter event, then drag
// events and then an exit event with no release.
//
// Just start pressing the mouse button dragging and releasing
// really fast. This bug occurs with light weights and heavy
// weights (just change LW to derive from Canvas).
//
// JDK1.1.5J, Windows NT 4.0 SP3
// ###@###.###
public class test {
public static void main(String[] args) {
System.out.println("Move the mouse into the black square. Press\n" +
"the mouse button and quickly exit the square while\n" +
"releasing the mouse button. If you perform this quickly\n" +
"enough, the only events generated are MOUSE_PRESSED and\n" +
"MOUSE_EXITED. Without a MOUSE_RELEASED event, a component\n" +
"that expects correct mouse behavior will behave incorrectly.\n" +
"Also, AWT will sometimes generate the enter event, then drag\n" +
"events and then an exit event with no release.\n\n" +
"Just start pressing the mouse button dragging and releasing\n" +
"really fast. This bug occurs with light weights and heavy\n" +
"weights (just change LW to derive from Canvas.");
Frame f = new Frame("test");
f.setBounds(100, 100, 200, 200);
LW lw = new LW();
f.add(lw);
f.show();
}
}
class LW extends Component {
boolean mouseIsPressed;
Color squareColor = Color.black;
boolean gettingDrags;
boolean doPrint = true;
MouseEvent lastEvent;
public LW() {
enableEvents(MouseEvent.MOUSE_EVENT_MASK |
MouseEvent.MOUSE_MOTION_EVENT_MASK);
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
Dimension size = getSize();
g.setColor(squareColor);
g.fillRect(1, 1, size.width - 1, size.height - 1);
g.setColor(Color.white);
String s;
if (mouseIsPressed)
s = "pressed";
else
s = "released";
g.drawString(s, 10, 15);
}
public void processMouseMotionEvent(MouseEvent e) {
if (!doPrint)
return;
System.out.println(e);
if (e.getID() == MouseEvent.MOUSE_DRAGGED)
gettingDrags = true;
lastEvent = e;
}
public void processMouseEvent(MouseEvent e) {
if (!doPrint)
return;
System.out.println(e);
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
mouseIsPressed = true;
gettingDrags = false;
repaint();
} else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
mouseIsPressed = false;
repaint();
} else if (e.getID() == MouseEvent.MOUSE_EXITED && mouseIsPressed
&& !gettingDrags) {
// ERROR
System.out.println("******* ERROR ********");
if (lastEvent.getID() == MouseEvent.MOUSE_PRESSED)
System.out.println("*** Mouse exited received without a\n" +
"release event and no drag events were being generated\n" +
"after mouse button pressed.");
if (lastEvent.getID() == MouseEvent.MOUSE_DRAGGED)
System.out.println("*** Mouse exited received without a\n" +
"release event between the last drag and the exit after\n" +
"mouse button pressed.");
squareColor = Color.red;
doPrint = false;
repaint();
}
lastEvent = e;
}
}
======================================================================