JDK-6427285 : Mouse listener for JComponent doesn't get MOUSE_CLICKED event when popup is shown on MOUSE_RELEASED
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-05-18
  • Updated: 2011-04-29
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Right click events are not always generated when you have a JTable with a JPopupMenu.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Open a frame with a JTable and a JPopupMenu. A MouseListener is receiving the mouse clicked events on the table.
2) Now, try right clicking on the first cell, the popup opening but the mouse clicked event is not generated. Right click on the others cells, the event is generated.
3) Now, resize the frame, the right click event is not generated at all.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I am expecting to receive all the right click events.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.*;
import javax.swing.table.*;

public class TablePopup {
		
	private static class MouseHandler extends MouseAdapter {
		public void mouseReleased(MouseEvent event) {
			if (event.isPopupTrigger()) {
				JPopupMenu popup = new JPopupMenu();
				popup.add(new JMenuItem("Menu1"));
				popup.add(new JMenuItem("Menu2"));
				popup.show(event.getComponent(), event.getX(), event.getY());
			}
		}
		public void mouseClicked(MouseEvent event) {
			System.out.println("Mouse clicked!");
		}
	}
	
	public static void main(String[] args) {
		DefaultTableModel model = new DefaultTableModel();
		JTable table = new JTable(model);
		model.addColumn("Col1");
		model.addColumn("Col2");
		model.addRow(new Object[]{"v1", "v2"});
		model.addRow(new Object[]{"v3", "v4"});
		model.addRow(new Object[]{"v5", "v6"});
		model.addRow(new Object[]{"v6", "v7"});
		
		table.addMouseListener(new MouseHandler());
						
		JFrame frame = new JFrame();
		frame.getContentPane().setLayout(new BorderLayout());
		frame.getContentPane().add(table, BorderLayout.CENTER);
		frame.pack();
		frame.setVisible(true);
	}
}

---------- END SOURCE ----------

Comments
WORK AROUND It is need to shift by one pixel the popup menu before it will be shown: popup.show(event.getComponent(), event.getX() + 1, event.getY());
16-11-2010

EVALUATION To me this sounds like an inconsistency with AWT. Re-assigning.
16-06-2006

EVALUATION I found the cause. It is in the Container class in the LightweightDispatcher.processMouseEvent() method. If the MOUSE_CLICKED event is come, a mouse event target and the component, on which mouse is over, are compared. If they are the same, the MOUSE_CLICKED event is sent to the component. If they are not the same, the MOUSE_CLICKED event is not sent. There is a comment for this code: // 4508327: MOUSE_CLICKED should never be dispatched to a Component // other than that which received the MOUSE_PRESSED event. If the // mouse is now over a different Component, don't dispatch the event. // The previous fix for a similar problem was associated with bug // 4155217. There is another point: the mouse event target and the component, on which mouse is over, differs only if popup menu is lightweight. If it is heavyweight, they are equal and MOUSE_CLICKED is sent to the component. Such behavior is caused by the code in couple of lines above in the same processMouseEvent() method: Component mouseOver = // sensitive to mouse events nativeContainer.getMouseEventTarget(e.getX(), e.getY(), Container.INCLUDE_SELF); If we look into the getMouseEventTarget() method, we see that the mouse event target is searched only for lightweight components. When popup menu is heavyweight it is not returned by the getMouseEventTarget() method and all is OK. I can suggest a simple workaround to get the MOUSE_CLICKED event in the test case. It is need to shift by one pixel the popup menu before it will be shown: popup.show(event.getComponent(), event.getX() + 1, event.getY());
31-05-2006

EVALUATION I found out that we can replace JTable in the test case by JButton or JPanel and bug will remain. Also if I replace background swing component by AWT one (ex. Panel) or replace JPopupMenu by AWT one (PopupMenu) the Mouse Clicked event is generated.
26-05-2006

EVALUATION I can reproduce the bug. Really, when popup is heavyweight, JTable gets events, but it doesn't when it is lightweight.
26-05-2006

EVALUATION The table gets the clicked event if a heavyweight popup is shown, but does not if the popup is lightweight.
25-05-2006