United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7082443 JComboBox not backward compatible (with Java 6)
JDK-7082443 : JComboBox not backward compatible (with Java 6)

Details
Type:
Bug
Submit Date:
2011-08-23
Status:
Resolved
Updated Date:
2013-04-22
Project Name:
JDK
Resolved Date:
2012-02-07
Component:
client-libs
OS:
linux
Sub-Component:
javax.swing
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
1.7.0

ADDITIONAL OS VERSION INFORMATION :
Ubuntu 10.10

A DESCRIPTION OF THE PROBLEM :
The JLabels in the dropdown box were opaque in Java 6, but not anymore in Java 7.
(Ubuntu System LaF)

REGRESSION.  Last worked in version 6u26

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
execute this code:


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

public class DebugColorChooser {

    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {

                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                System.out.println("os: " + System.getProperty("os.name"));
                System.out.println("jvm: " + System.getProperty("java.version"));
                JFrame frame = new JFrame();
                JPanel panel = new JPanel();
                JComboBox jcb = new MyComboBox(new String[]{"Test1", "Test2"});
                panel.add(jcb);
                frame.getContentPane().add(panel);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    public static class MyComboBox extends JComboBox {

        public MyComboBox(Object[] items) {
            super(items);
        }

        @Override
        public ListCellRenderer getRenderer() {
            ListCellRenderer dfltRenderer = super.getRenderer();
            return changeRenderer(dfltRenderer);
        }

        private ListCellRenderer changeRenderer(final ListCellRenderer listCellRenderer) {
            if (null != listCellRenderer) {
                ListCellRenderer colorCellRenderer = new ListCellRenderer() {

                    @Override
                    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                        JLabel label = (JLabel) listCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                        System.out.println("opaque: " + label.isOpaque());
                        return label;
                    }
                };
                return colorCellRenderer;
            }
            return null;
        }
    }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
opaque: true
ACTUAL -
opaque: false

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public static class MyComboBox extends JComboBox {

        public MyComboBox(Object[] items) {
            super(items);
        }

        @Override
        public ListCellRenderer getRenderer() {
            ListCellRenderer dfltRenderer = super.getRenderer();
            return changeRenderer(dfltRenderer);
        }

        private ListCellRenderer changeRenderer(final ListCellRenderer listCellRenderer) {
            if (null != listCellRenderer) {
                ListCellRenderer colorCellRenderer = new ListCellRenderer() {

                    @Override
                    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                        JLabel label = (JLabel) listCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                        System.out.println("opaque: " + label.isOpaque());
                        return label;
                    }
                };
                return colorCellRenderer;
            }
            return null;
        }
    }
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
public static class MyComboBox extends JComboBox {

        public MyComboBox(Object[] items) {
            super(items);
        }

        @Override
        public ListCellRenderer getRenderer() {
            ListCellRenderer dfltRenderer = super.getRenderer();
            return changeRenderer(dfltRenderer);
        }

        private ListCellRenderer changeRenderer(final ListCellRenderer listCellRenderer) {
            if (null != listCellRenderer) {
                ListCellRenderer colorCellRenderer = new ListCellRenderer() {

                    @Override
                    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                        JLabel label = (JLabel) listCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                        label.setOpaque(true);
                        return label;
                    }
                };
                return colorCellRenderer;
            }
            return null;
        }
    }

                                    

Comments
EVALUATION

SynthComboBoxRenderer should have installed Name while constructor is working. The setName invocation (as currently implemented) in the SynthComboBoxRenderer() constructor doesn't work because of the opaque property is installed in the constructor based on the component name (see GTKStyle.isOpaque()). Currently setName tries update style (and defaults as well) but cannot do that, because between SynthComboBoxRenderer and setName style is not changed. As a result the SynthLookAndFeel#updateStyle skips style updating (see line if (newStyle != oldStyle)). 

The simplest fix is to override the getName, as currently done in the com.sun.java.swing.plaf.gtk.GTKFileChooserUI.FilterComboBoxRenderer#getName method.
                                     
2011-11-15



Hardware and Software, Engineered to Work Together