JDK-7181403 : Invalid MouseEvent conversion with SwingUtilities.convertMouseEvent
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u31
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2012-07-03
  • Updated: 2014-10-06
  • Resolved: 2013-03-01
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 7 JDK 8
7u40Fixed 8 b82Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_33"
Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
Java HotSpot(TM) Client VM (build 20.8-b03, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [version 6.0.6002]

A DESCRIPTION OF THE PROBLEM :
Due to the bugs 4988798 (Closed - Not Fixed) and similarly 4522626, the conversion of a MouseEvent with SwingUtilities.convertMouseEvent() is invalid.
The initial modifiers and extended modifiers are incorrectly converted.
(due to private method setNewModifiers in MouseEvent).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the given sample and perform:
1) Right Click on the panel
2) Alt + Right Click on the panel
3) Meta + Left-Click on the panel (with a mac keyboard)

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
In each test case, the modifiers and extModifiers of the converted event must be the same as the modifiers and extModifiers in the initialEvent.
ACTUAL -
Right click:
Initial event: java.awt.event.MouseEvent[MOUSE_PRESSED,(63,29),absolute(171,157),button=3,modifiers=M��ta+Button3,extModifiers=Button3,clickCount=1] on com.test.BugMouseEvent[...]
Converted event: java.awt.event.MouseEvent[MOUSE_PRESSED,(63,29),absolute(171,157),button=3,modifiers=M��ta+Button3,extModifiers=M��ta+Button3,clickCount=1] on com.test.BugMouseEvent[...]

Alt + Left Click:
Initial event: java.awt.event.MouseEvent[MOUSE_PRESSED,(71,107),absolute(179,235),button=1,modifiers=Alt+Button1+Button2,extModifiers=Alt+Button1,clickCount=1] on com.test.BugMouseEvent[...]
Converted event: java.awt.event.MouseEvent[MOUSE_PRESSED,(71,107),absolute(179,235),button=1,modifiers=Button1,extModifiers=Button1+Button2,clickCount=1] on com.test.BugMouseEvent[...]

Meta + LeftClick:
Initial event: java.awt.event.MouseEvent[MOUSE_PRESSED,(60,105),absolute(170,232),button=1,modifiers=M��ta+Button1+Button2,extModifiers=M��ta+Button1,clickCount=1] on com.test.BugMouseEvent[...]
Converted event: java.awt.event.MouseEvent[MOUSE_PRESSED,(60,105),absolute(170,232),button=1,modifiers=Button1,extModifiers=Button1+Button3,clickCount=1] on com.test.BugMouseEvent[...]


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.event.*;

import javax.swing.*;

public class BugMouseEvent extends JPanel {
	public BugMouseEvent() {
		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				System.err.println("Initial event: " + e);
				MouseEvent ne = SwingUtilities.convertMouseEvent(e.getComponent(), e, e.getComponent());
				System.err.println("Converted event: " + ne);
			}
		});
	}
	public static void main(String[] args) {
		JFrame f = new JFrame("Test");
		f.getContentPane().add(new BugMouseEvent());
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setBounds(100, 100, 200, 200);
		f.setVisible(true);
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
As the bug in the MouseEvent constructor will not be corrected, the only way to correct the issue is to change the SwingUtilities.convertMouseEvent(). I duplicated this method in an other class and corrected the code:

[code]
	public static MouseEvent convertMouseEvent(Component source, MouseEvent sourceEvent, Component destination) {
		Point p = SwingUtilities.convertPoint(source, new Point(sourceEvent.getX(), sourceEvent.getY()), destination);
		Component newSource;
		if (destination != null) {
			newSource = destination;
		}
		else {
			newSource = source;
		}
		MouseEvent newEvent;
		if (sourceEvent instanceof MouseWheelEvent) {
			MouseWheelEvent sourceWheelEvent = (MouseWheelEvent)sourceEvent;
			newEvent = new MouseWheelEvent(newSource, sourceWheelEvent.getID(), sourceWheelEvent.getWhen(), sourceWheelEvent.getModifiersEx(), p.x, p.y, sourceWheelEvent.getXOnScreen(), sourceWheelEvent.getYOnScreen(), sourceWheelEvent.getClickCount(), sourceWheelEvent.isPopupTrigger(), sourceWheelEvent.getScrollType(), sourceWheelEvent.getScrollAmount(), sourceWheelEvent.getWheelRotation());
		}
		else if (sourceEvent instanceof MenuDragMouseEvent) {
			MenuDragMouseEvent sourceMenuDragEvent = (MenuDragMouseEvent)sourceEvent;
			newEvent = new MenuDragMouseEvent(newSource, sourceMenuDragEvent.getID(), sourceMenuDragEvent.getWhen(), sourceMenuDragEvent.getModifiersEx(), p.x, p.y, sourceMenuDragEvent.getXOnScreen(), sourceMenuDragEvent.getYOnScreen(), sourceMenuDragEvent.getClickCount(), sourceMenuDragEvent.isPopupTrigger(), sourceMenuDragEvent.getPath(), sourceMenuDragEvent.getMenuSelectionManager());
		}
		else {
			// initial code:
			// newEvent = new MouseEvent(newSource, sourceEvent.getID(), sourceEvent.getWhen(), sourceEvent.getModifiers(), p.x, p.y, sourceEvent.getXOnScreen(), sourceEvent.getYOnScreen(), sourceEvent.getClickCount(), sourceEvent.isPopupTrigger(), MouseEvent.NOBUTTON);
			// corrected code:
			newEvent = new MouseEvent(newSource, sourceEvent.getID(), sourceEvent.getWhen(), sourceEvent.getModifiersEx(), p.x, p.y, sourceEvent.getXOnScreen(), sourceEvent.getYOnScreen(), sourceEvent.getClickCount(), sourceEvent.isPopupTrigger(), sourceEvent.getButton());
		}
		return newEvent;
	}
[/code]

Comments
test\javax\swing\SwingUtilities\7170657\bug7170657.java
22-11-2013