Hi,
I am just posting this for the benefit of the list. We recently
uncovered a bug in one of our applications which uses VisAD. In short,
when showing a JPopupMenu above a Canvas, using Java 1.6 on Linux, Java
eats any mouse up event following a mouse down that caused you to
display the popup. This is a problem for VisAD as it maintains its own
copy of mouse button state which becomes invalid, so most mouse
behaviour stops working properly.
I have attached some sample code used to fix this, which creates a
new mouse up event. The comments also provide a better description of
the issue.
Hope it helps someone.
Andrew.
--
Andrew Donaldson
Meteorological Systems Development Manager
Bureau of Meteorology
ph 03 9669 4537
...
// Add popup listener
popupMenu.addPopupMenuListener(
new SelectionPopupMenuListener());
popupMenu.show(component, screen[0], screen[1]);
popupMenu.repaint();
}
/**
* This popup menu listener creates a MouseEvent of type MOUSE_RELEASED
* for BUTTON3 when the popup WillBecomeInvisible.
* This is a work around for a bug seen on Java 1.6 (up to _22) on
* Linux, where the MOUSE_RELEASED event following the MOUSE_PRESSED
* event which causes us to call popupMenu.show() goes missing.
* This bug is not seen with Java 1.5 on Linux or Windows, nor
* is it seen with Java 1.6 on Windows.
*
* The symptom seen in TC Module is that after a popup menu is
* displayed in the map area, all VisAD mouse presses appear to
* not work properly (or at all). This is because VisAD maintains
* its own mouse button states, which become incorrect if the
* MOUSE_RELEASED event for the right mouse button does not arrive.
* VisAD interprets a BUTTON1_PRESSED event while BUTTON3 is
* thought to be down, to be a virtual button press rather than a
* BUTTON1 press.
*
* This bug could have been fixed by changing VisAD to use the
* system mouse button state rather than using its own copy, however
* the fix implemented here is considered to be lower impact and
* more easily removed should Java 1.6 on Linux one day send the
* missing MOUSE_RELEASED event.
*/
private class SelectionPopupMenuListener implements PopupMenuListener
{
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
;
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
{
JPopupMenu popupMenu = (JPopupMenu)e.getSource();
Rectangle rectangle = popupMenu.getBounds();
Canvas canvas = displayRenderer.getCanvas();
MouseEvent mouseEvent = new MouseEvent(
canvas,
MouseEvent.MOUSE_RELEASED,
(new java.util.Date()).getTime(),
MouseEvent.BUTTON3_MASK,
(int)rectangle.getX(),
(int)rectangle.getY(),
1, false);
canvas.dispatchEvent(mouseEvent);
}
public void popupMenuCanceled(PopupMenuEvent e)
{
;
}
}