JDK-6309495 : JMenuItem and TrayIcon does not work when in same application
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux,windows_xp
  • CPU: x86
  • Submitted: 2005-08-11
  • Updated: 2010-04-02
  • Resolved: 2005-11-09
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 6
6 b60Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-ea"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-ea-b46)
Java HotSpot(TM) Client VM (build 1.6.0-ea-b46, mixed mode, sharing)

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

A DESCRIPTION OF THE PROBLEM :
When a JMenuItem is displayed and the same application (running in the same JVM) has a TrayIcon, errors occur when clicking on the tray icon.  A ClassCastException occurs which comes from javax.swing.plaf.basic.BasicLookAndFeel$AWTEventHelper.eventDispatched.  This class seems to run through all mouse events in the AWT in order to process menu popups.

My guess to the cause of the problem is line 2086 in AWTEventHelper.eventDispatched().  The code is attempting to cast the source of a mouse event into a java.awt.Component, assuming that all sources of mouse events are Components.  While this might have been true for JDK 1.5 and earlier, in JDK 1.6 TrayIcons can also generate mouse events and they are NOT subclasses of java.awt.Component.

An instanceof check in AWTEventHelper.eventDispatched() should fix this bug.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code in the test case specified.  The stack trace occurs when clicking on the tray icon.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception occurred during event dispatching:
java.lang.ClassCastException: java.awt.TrayIcon cannot be cast to java.awt.Component
	at javax.swing.plaf.basic.BasicLookAndFeel$AWTEventHelper.eventDispatched(BasicLookAndFeel.java:2086)
	at java.awt.Toolkit$SelectiveAWTEventListener.eventDispatched(Toolkit.java:2274)
	at java.awt.Toolkit.notifyAWTEventListeners(Toolkit.java:2126)
	at java.awt.TrayIcon.dispatchEvent(TrayIcon.java:605)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:270)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:198)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:171)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:166)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:158)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:119)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class TestMenuAndTray
{
    public static void main(String[] args)
    {
        JFrame pFrame = new JFrame("Good Morning");
        JMenuBar myBar = new JMenuBar();
        JMenu myMenu = new JMenu("File");
        myBar.add(myMenu);
        JMenuItem open = new JMenuItem("Open...");
        myMenu.add(open);
        pFrame.setJMenuBar(myBar);
        pFrame.pack();
        pFrame.setVisible(true);
	
        SystemTray tray = SystemTray.getSystemTray();
        Image image = Toolkit.getDefaultToolkit().getImage("appicon.jpg");
        TrayIcon myIcon = new TrayIcon(image);
        tray.add(myIcon);
    }
}
---------- END SOURCE ----------

Comments
EVALUATION In eventDispatched in BasicLookAndFeel.java there is code to activate the JInternalFrame containing the component on which there was a MOUSE_PRESSED event. If the object returned by the event getSource() is not a Component, then casting it as a Component will cause a java.lang.ClassCastException. Check if the object returned by the event getSource() is not a Component. If so, then the code that follows does not apply because a non-Component is never within a JInternalFrame, so return from the method.
20-10-2005

EVALUATION An instanceof check in AWTEventHelper.eventDispatched() should fix this bug. Looks like a low risk fix.
17-10-2005

EVALUATION This regression was introduced by the fix to 4398733.
11-08-2005