JDK-4895924 : Strings in format #rgb not handled by Color.decode() (affects CSS / Swing)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.1_06,1.4.1,1.4.1_03,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux,windows_2000
  • CPU: x86
  • Submitted: 2003-07-24
  • Updated: 2025-12-03
  • Resolved: 2019-02-26
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 11 JDK 13
11.0.30Fixed 13 b10Resolved
Related Reports
Duplicate :  
Relates :  
Description

Name: jk109818			Date: 07/24/2003


FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)


FULL OPERATING SYSTEM VERSION :
Linux jupiter 2.4.19-4GB #1 Fri Sep 13 13:19:15 UTC 2002
i686 unknown


A DESCRIPTION OF THE PROBLEM :
I wrote a simple web browser using the JEditorPane class.
When I viewed some sites, I detected that JEditorPane
displayed wrong colors. When I took a look at the style
sheets, I detected that the colors were given in three
instead  of six sedecimal digits, like
"background-color:#eee";, which is completely legal CSS and
should be expanded to #eeeeee; on 24 bit color systems.
Java does not expand #eee; to #eeeeee; but instead to
#000eee; which of course produces the wrong colors.

I believe that Swing simply uses AWT's
Color.decode(String)-Method to create the required Color object.

I've found out that Color.decode() doesn't handle
3-digit-color values as they may be used in CSS.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Write a browser (source below)
2. Run it
3. load the page (source below)

Or:
1. Create a Color-Object.
2. Print it out.
3. Look at it's RGB values

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected result: light light gray background
Actual result: blue background

Interpretation:
Instead of expanding #eee to #eeeeee to generate the color
value, #eee is interpreted as #000eee;

Or:

System.out.println(Color.decode("#eee"));
expected result: java.awt.Color[r=238,g=238,b=238]
actual result: java.awt.Color[r=0,g=14,b=238]


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Source code of Java Browser:

import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.html.HTMLFrameHyperlinkEvent;
import javax.swing.text.html.HTMLDocument;

public class Browser extends JFrame implements HyperlinkListener {

    public static final String revision = "$Revision: 1.7 $";

    private static Browser b;

    public static void main(final String[] args) throws IOException,
MalformedURLException {
        if ("1.4.0".compareTo(System.getProperty("java.version")) >= 0) {
            JDialog.setDefaultLookAndFeelDecorated(true);
            JFrame.setDefaultLookAndFeelDecorated(true);
            Toolkit.getDefaultToolkit().setDynamicLayout(true);
        }
        if (args.length != 0) {
            b = new Browser(args[0]);
        } else {
            b = new Browser();
        }
        // System.out.println(Toolkit.getDefaultToolkit().getScreenSize());
        b.setSize(Toolkit.getDefaultToolkit().getScreenSize());
        b.setVisible(true);
        b.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        b.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                b.dispose();
                b = null;
            }
        });
    }

    private JEditorPane browser;

    public Browser() throws IOException, MalformedURLException {
        this("file:///usr/lib/jax/sun/j2sdkse/latest/docs/index.html");
    }

    public Browser(final String url) throws IOException, MalformedURLException {
        super(url);
        browser = new JEditorPane(new URL(url));
        browser.setEditable(false);
        browser.addHyperlinkListener(this);
        JScrollPane scroll = new JScrollPane(browser);
        getContentPane().add(scroll);
    }

    public void hyperlinkUpdate(final HyperlinkEvent e) {
        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
            JEditorPane pane = (JEditorPane) e.getSource();
            if (e instanceof HTMLFrameHyperlinkEvent) {
                HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e;
                HTMLDocument doc = (HTMLDocument) pane.getDocument();
                doc.processHTMLFrameHyperlinkEvent(evt);
            } else {
                try {
                    pane.setPage(e.getURL());
                } catch (Throwable t) {
                    t.printStackTrace();
                }
            }
        }
    }
}


Source code of html / css file demonstrating the problem:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>Problem</title>
        <style type="text/css">
            body {
                background-color:#eee;
            }
        </style>
    </head>
    <body>
        <h1>Text</h1>
    </body>
</html>


Or source code demonstrating the problem with class Color:
import java.awt.Color;

public class ColorTest {
    public static void main(String[] args) {
        System.out.println("The following two should be equal:");
        System.out.println(Color.decode("#eeeeee"));
        System.out.println(Color.decode("#eee"));
        assert
            Color.decode("#eee").equals(Color.decode("#eeeeee")) :
            "3 hex-digit Colors must be interpreted the same way as their
corresponding 6 hex-digit Colors";
    }
}

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

CUSTOMER WORKAROUND :
There is no workaround for this possible, as one can't
change other site's stylesheets.


I think the bug can be fixed by changing
java.awt.Color.decode() to: (untested)

    /**
     * Converts a <code>String</code> to an integer and
returns the
     * specified opaque <code>Color</code>. This method
handles string
     * formats that are used to represent octal and
hexidecimal numbers.
     * @param      nm a <code>String</code> that represents
     *                            an opaque color as a
24-bit integer
     *                            or as a 12-bit sedecimal
integer #rgb
     * @return     the new <code>Color</code> object.
     * @see        java.lang.Integer#decode
     * @exception  NumberFormatException  if the specified
string cannot
     *                      be interpreted as a decimal,
     *                      octal, or hexidecimal integer.
     * @since      JDK1.1
     */
    public static Color decode(final String nm) throws
NumberFormatException {
        Integer intval;
        if (nm.startsWith("#") && nm.length() == 4) {
            intval = Integer.decode("#" + nm.charAt(1) +
nm.charAt(1) + nm.charAt(2) + nm.charAt(2) + nm.charAt(3) +
nm.charAt(3));
        } else {
            intval = Integer.decode(nm);
        }
        int i = intval.intValue();
        return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF,
i & 0xFF);
    }
(Incident Review ID: 179135) 
======================================================================

Comments
[jdk11u-fix-request] Approval Request from Mangovnik Clean back port fixing background rendering for some webpages when JEditorPane is used. Tests run on fedora 43. Gtests passed, same T1 failing before and after the backport - not related to this issue.
20-11-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk11u-dev/pull/3118 Date: 2025-11-12 16:34:52 +0000
20-11-2025

URL: http://hg.openjdk.java.net/jdk/jdk/rev/a986e16d8449 User: psadhukhan Date: 2019-02-27 09:16:08 +0000
27-02-2019

URL: http://hg.openjdk.java.net/jdk/client/rev/a986e16d8449 User: psadhukhan Date: 2019-02-26 05:38:27 +0000
26-02-2019

EVALUATION Color.java belongs to 2D. ###@###.### 2003-07-24 Color.decode() specifies that it converts a string to an integer. It is using Integer.decode() to perform the conversion. It does not specify that the decoded string is in a format that is understood to be a CSS string. This means that Swing cannot count on just being able to pass an HTML CSS string into Color.decode and get the correct interpretation. ###@###.### 2003-07-24
24-07-2003