JDK-4913321 : REGRESSION:JDK1.5.0-b16, Metal LAF color overrides components custom colors
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS:
    generic,linux_suse_sles_8.2,windows_2000 generic,linux_suse_sles_8.2,windows_2000
  • CPU: generic,x86
  • Submitted: 2003-08-27
  • Updated: 2005-04-26
  • Resolved: 2003-12-04
Related Reports
Duplicate :  
Description

Name: jbT81659			Date: 08/27/2003

Locale: Windows, Solaris, (Linux not tested)
Regression: NO
Build: b16
This bug affects all test cases. The problem is specific only to jdk1.5.0-b16 not earlier builds. The Metal LookAndFeel imposes a light blue color over compnents custom colors set by the pogrammer inside applications and applets. 
Component color is overrided with the Metal LAF blue color. For example, picking a color from JColorChooser and applying it to a JButton will not have any effect, the JButton will still have the blue color from the Metal LAF.

Testcase:

Run the following code (jLayeredPane.java) with these commands for Motif and Metal LAF's

java -Dswing.defaultlaf=com.sun.java.swing.plaf.motif.MotifLookAndFeel jLayeredPane
java -Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel jLayeredPane

-------------------------------------------------------------------------------------
/* Copyright (c) Sun Microsystems 1998

$Header: /home-bazelet/sun/src/javaLab/JDK1.4/LAF/jLayeredPane.java,v 1.1.1.1 2001/06/19 15:01:25 isam Exp $

*/

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

public class jLayeredPane extends JApplet
{

	public void init()
   	{
		jLayeredPane1 lpane = new jLayeredPane1();
		//getContentPane().add(lpane);
        }

	public static void main(String[] argv)
	{
		jLayeredPane1 lpane = new jLayeredPane1();
		//getContentPane().add(lpane);
	}

}



class jLayeredPane1 extends JPanel
{

	public jLayeredPane1()
	{


                this.setLayout(new BorderLayout());
                setLayout(new FlowLayout());
   		JFrame f = new JFrame();
    		JLayeredPane lp = f.getLayeredPane();
    		JButton top = new JButton("\u05dc\u05d1\u05df\u0020");
                top.setFont(new Font("Lucida Sans Regular", Font.PLAIN, 18));
                top.setBackground(Color.white);
    		top.setBounds(10, 10, 90,90);
    		JButton middle = new JButton("\u0631\u0645\u0627\u062f\u064a");
                middle.setFont(new Font("Lucida Sans Regular", Font.PLAIN, 18));
    		middle.setBackground(Color.gray);
    		middle.setBounds(60, 60, 100, 100);
    		JButton bottom = new JButton("\u0623\u0633\u0648\u062f\u0020\u05e9\u05d7\u05d5\u05e8");
                bottom.setFont(new Font("Lucida Sans Regular", Font.PLAIN, 18));
                bottom.setBackground(Color.red);
    		bottom.setBounds(140, 140, 200, 200);
    		lp.add(middle, new Integer(2));
    		lp.add(top, new Integer(3));
    		lp.add(bottom, new Integer(1));
    		f.setSize(500, 500);
    		f.setVisible(true);
        f.addWindowListener( new WindowAdapter()
        {
             public void windowClosing( WindowEvent e)
             {
                 System.exit(0);
             }
        });

  	}
}

-------------------------------------------------------------------------------------

1. Under Motif each button is displayed with its set color(red, gray, white)
2. Under Metal all buttons are displayed with the LAF color (blue)

======================================================================


###@###.### 2003-11-11

CAP member reported the same problem:

J2SE Version (please include all output from java -version flag):
  java version "1.5.0-beta"
  Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b26)
  Java HotSpot(TM) Client VM (build 1.5.0-beta-b26, mixed mode)

Does this problem occur on J2SE 1.4 or 1.4.1 or 1.4.2?  Yes / No (pick one)
  No

Operating System Configuration Information (be specific):
  SuSE Linux 8.2

Hardware Configuration Information (be specific):
  Intel PC x586

Bug Description:
  setting the color of a JButton like this
         jb.setBackground(Color.red);
  does work in 1.4.2, but not in 1.5.0
  (background: I use an application with colored buttons)

Steps to Reproduce (be specific):
  1. compile the enclosed code with J2SE 1.4.2 and
     run the program. The button is red
  2. do the same with J2SE 1.5.0
     button color is unchanged

Test program:
****************** code to reproduce the behavior *****************
import java.awt.*;
import javax.swing.*;

public class ColorButtonTest extends JFrame{
     public ColorButtonTest() {
         JFrame jf = new JFrame("ColorButtonTest");
         JButton jb = new JButton("please wait 3 seconds"
                         + " for self-destruction...");
         // the following line has effect in J2SE 1.4.2, but not in 1.5.0
         jb.setBackground(Color.red);

         jf.getContentPane().add(jb);
         jf.setSize(400,100);
         jf.setVisible(true);
         try { Thread.sleep(3000);
         } catch (InterruptedException e){
         }
         jf.dispose();
         System.exit(0);
     }
     public static void main(String[] args) {
         new ColorButtonTest();
     }
}
****************** code to reproduce the behavior *****************


###@###.### 2003-11-19

same problem reported by another CAP member:

Bug Description:
  The bug was found testing the 1.5 release.  The problem is that the JButton's
  setBackground() method does not work.  To extend JButton and
  overrides the setBackground() method, the first call in that method is 
  super.setBackground(color).  The setForeground() method seems to work fine.

----test program-----------

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class JButtonBGTest
{
    private static Color toggleColor = Color.YELLOW;
    private static int lnfCounter = 1;

    public static void main( String[] args )
    {
        final JFrame buttonFrame = new JFrame( "Button Backgound Test" );
        buttonFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        JButton defaultButton = new JButton( "Default" );
        JButton redButton = new JButton( "Red Button" );
        redButton.setBackground( Color.RED );
        final JButton toggleButton = new JButton( "Toggle Button" );
        toggleButton.setBackground( Color.YELLOW );
        toggleButton.addActionListener( new ActionListener()
        {
            public void actionPerformed( ActionEvent e )
            {
                if ( toggleColor == Color.YELLOW )
                {
                System.out.println( "toggleButton.changing Color to blue" );
                    toggleColor = Color.BLUE;
                }
                else
                {
                System.out.println( "toggleButton.changing Color to yellow" 
);
                    toggleColor = Color.YELLOW;
                }

                toggleButton.setBackground( toggleColor );
            }
        } );


        final LookAndFeelInfo[] lnfs = UIManager.getInstalledLookAndFeels();

        JButton lnfButton = new JButton( "Cycle LNF" );
        lnfButton.addActionListener( new ActionListener()
        {
            public void actionPerformed( ActionEvent event )
            {
                try
                {
                    lnfCounter = lnfCounter >= lnfs.length ? 0 : lnfCounter;
                    javax.swing.UIManager.setLookAndFeel(
                        lnfs[lnfCounter++].getClassName() );
                System.out.println( "Changed LNF to "
                    + lnfs[lnfCounter-1].getClassName() );

                    buttonFrame.validate();
                    buttonFrame.repaint();
                }
                catch ( Exception e )
                {
                    // this is only a test - no need to perform proper error
                    // handling
                    e.printStackTrace();
                }
            }
        } );

        Container contentPane = buttonFrame.getContentPane();
        contentPane.setLayout( new FlowLayout() );
        contentPane.add( defaultButton );
        contentPane.add( redButton );
        contentPane.add( toggleButton );
        contentPane.add( Box.createHorizontalStrut( 15 ) );
        contentPane.add( lnfButton );

        buttonFrame.setSize( 400, 200 );
        buttonFrame.setVisible( true );
    }
}




Comments
EVALUATION How a component draws it's background is look and feel specific. With the new Ocean look and feel buttons don't draw the background, instead they use the gradient you are seeing. If you want the old metal look and feel, which will honor the background, use the system property: swing.metalTheme=steel ###@###.### 2003-08-27 This has been addressed by 4908404, refer to it for details. ###@###.### 2003-12-04
27-08-2003