United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6554551 JMenu Items Won't Render Icons
JDK-6554551 : JMenu Items Won't Render Icons

Details
Type:
Bug
Submit Date:
2007-05-07
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
client-libs
OS:
windows_vista
Sub-Component:
javax.swing
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Backport:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Windows Vista

A DESCRIPTION OF THE PROBLEM :
Enabling system look and feel for Vista causes JMenu items with icons specified (i.e. passing an AbstractAction instance to the JMenu constructor) not to render the icon.

This only occurs in the update to JRE 1.6. The standard 1.6 release doesn't render JMenu items with the improved Vista look and feel, hence the issue doesn't occur.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Define a class extending AbstractAction. Ensure a constructor is specified that accepts a String and Icon. Pass the String and Icon to the super() method.

Create a class that extends JFrame. Create a JMenu instance, passing the AbstractAction extending class. Add this JMenu instance to to a JMenuBar. Add the JMenuBar to the frame.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The icon specified for the JMenu item should render.
ACTUAL -
The icon specified for the JMenu item doesn't render.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*********
TestAction.java
*********/
package com.menutest;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TestAction extends AbstractAction {
	
	public TestAction(String name, Icon icon) {
		super(name, icon);
	}

	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
	}
}

/***********
MenuTest.java
***********/

package com.menutest;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MenuTest extends JFrame{

	  public static void main(String [] args)throws Exception{
		    setLookAndFeel();
		    
		    MenuTest menuTest = new MenuTest();
		  }
	
	  public MenuTest() {
	        super("Testing JMenu items with Vista look and feel");
	        
	        JMenuBar menuBar = new JMenuBar();
	        TestAction testAction = new TestAction("Menu1", new ImageIcon(getClass().getResource("Small_Logo.png")));
	        JMenu menuItem = new JMenu(testAction);
	        
	        menuBar.add(menuItem);

	        this.setJMenuBar(menuBar);
	        
	        // Display the JFrame.
	        this.setSize(new Dimension(690, 450));
	        this.setVisible(true);
	        
	        // Adding a listener to detect if the JFrame is closing, to close the application if needed.
	        addWindowListener(new WindowAdapter() {
	            public void windowClosing(WindowEvent e) {
	                System.exit(0);
	            }
	        });
	  }
	  
	  private static void setLookAndFeel() {
		    try {
		      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		    }
		    catch(Exception e) {
		      System.err.println("Error setting Windows LAF");
		      e.printStackTrace();
		    }
		  }
}
---------- END SOURCE ----------

                                    

Comments
EVALUATION

On Vista menu icon is painted by checkIcon. However there is a case
when checkIcon is not used and because of that menu icon is not
painted. This case is top level JMenu. For this case we need to paint
icon as before without relying on checkIcon.

----
*** /tmp/geta4761	Mon Jun  4 16:17:37 2007
--- BasicMenuItemUI.java	Mon Jun  4 16:15:51 2007
***************
*** 435,445 ****
          /* 
           * in case .checkIconFactory is defined for this UI and the icon is 
           * compatible with it then the icon is handled by the checkIcon.
           */
          MenuItemCheckIconFactory iconFactory = 
              (MenuItemCheckIconFactory) UIManager.get(getPropertyPrefix() 
                  + ".checkIconFactory");
!         if (iconFactory == null
                  || ! iconFactory.isCompatible(checkIcon, getPropertyPrefix())) {
             icon = b.getIcon();  
          }
--- 435,447 ----
          /* 
           * in case .checkIconFactory is defined for this UI and the icon is 
           * compatible with it then the icon is handled by the checkIcon.
+          * That is if useCheckAndArrow() is true.
           */
          MenuItemCheckIconFactory iconFactory = 
              (MenuItemCheckIconFactory) UIManager.get(getPropertyPrefix() 
                  + ".checkIconFactory");
!         if (! useCheckAndArrow() 
!                 || iconFactory == null
                  || ! iconFactory.isCompatible(checkIcon, getPropertyPrefix())) {
             icon = b.getIcon();  
          }
***************
*** 659,669 ****
          /* 
           * in case .checkIconFactory is defined for this UI and the icon is 
           * compatible with it then the icon is handled by the checkIcon.
           */
          MenuItemCheckIconFactory iconFactory = 
              (MenuItemCheckIconFactory) UIManager.get(getPropertyPrefix() 
                  + ".checkIconFactory");
!         if (iconFactory == null
                  || ! iconFactory.isCompatible(checkIcon, getPropertyPrefix())) {
             icon = b.getIcon();  
          }
--- 661,673 ----
          /* 
           * in case .checkIconFactory is defined for this UI and the icon is 
           * compatible with it then the icon is handled by the checkIcon.
+          * That is if useCheckAndArrow() is true.
           */
          MenuItemCheckIconFactory iconFactory = 
              (MenuItemCheckIconFactory) UIManager.get(getPropertyPrefix() 
                  + ".checkIconFactory");
!         if (! useCheckAndArrow() 
!                 || iconFactory == null
                  || ! iconFactory.isCompatible(checkIcon, getPropertyPrefix())) {
             icon = b.getIcon();  
          }
----
                                     
2007-06-04



Hardware and Software, Engineered to Work Together