Skip to content

Commit 44c8379

Browse files
committedJan 13, 2021
8256019: JLabel HTML text does not support translucent text colors
Reviewed-by: serb
1 parent 0957d9e commit 44c8379

File tree

2 files changed

+196
-6
lines changed

2 files changed

+196
-6
lines changed
 

‎src/java.desktop/share/classes/javax/swing/text/html/CSS.java

+21-6
Original file line numberDiff line numberDiff line change
@@ -1387,7 +1387,7 @@ static final Color hexToColor(String value) {
13871387

13881388
/**
13891389
* Convert a color string such as "RED" or "#NNNNNN" or "rgb(r, g, b)"
1390-
* to a Color.
1390+
* or "rgba(r, g, b, a)" to a Color.
13911391
*/
13921392
static Color stringToColor(String str) {
13931393
Color color;
@@ -1399,6 +1399,8 @@ static Color stringToColor(String str) {
13991399
color = Color.black;
14001400
else if (str.startsWith("rgb(")) {
14011401
color = parseRGB(str);
1402+
} else if (str.startsWith("rgba(")) {
1403+
color = parseRGBA(str);
14021404
}
14031405
else if (str.charAt(0) == '#')
14041406
color = hexToColor(str);
@@ -1452,20 +1454,33 @@ private static Color parseRGB(String string) {
14521454
int[] index = new int[1];
14531455

14541456
index[0] = 4;
1455-
int red = getColorComponent(string, index);
1456-
int green = getColorComponent(string, index);
1457-
int blue = getColorComponent(string, index);
1457+
int red = (int)getColorComponent(string, index);
1458+
int green = (int)getColorComponent(string, index);
1459+
int blue = (int)getColorComponent(string, index);
14581460

14591461
return new Color(red, green, blue);
14601462
}
14611463

1464+
private static Color parseRGBA(String string) {
1465+
// Find the next numeric char
1466+
int[] index = new int[1];
1467+
1468+
index[0] = 4;
1469+
float red = getColorComponent(string, index)/255f;
1470+
float green = getColorComponent(string, index)/255f;
1471+
float blue = getColorComponent(string, index)/255f;
1472+
float alpha = getColorComponent(string, index);
1473+
1474+
return new Color(red, green, blue, alpha);
1475+
}
1476+
14621477
/**
14631478
* Returns the next integer value from <code>string</code> starting
14641479
* at <code>index[0]</code>. The value can either can an integer, or
14651480
* a percentage (floating number ending with %), in which case it is
14661481
* multiplied by 255.
14671482
*/
1468-
private static int getColorComponent(String string, int[] index) {
1483+
private static float getColorComponent(String string, int[] index) {
14691484
int length = string.length();
14701485
char aChar;
14711486

@@ -1501,7 +1516,7 @@ private static int getColorComponent(String string, int[] index) {
15011516
index[0]++;
15021517
value = value * 255f / 100f;
15031518
}
1504-
return Math.min(255, Math.max(0, (int)value));
1519+
return Math.min(255f, Math.max(0, value));
15051520
} catch (NumberFormatException nfe) {
15061521
// Treat as 0
15071522
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
/*
24+
* @test
25+
* @bug 8256019
26+
* @summary Verifies if JLabel HTML text support translucent text colors
27+
* @run main/manual TestTranslucentLabelText
28+
*/
29+
30+
import java.awt.BorderLayout;
31+
import java.awt.Color;
32+
import java.awt.Dimension;
33+
import java.awt.Font;
34+
import java.awt.FlowLayout;
35+
import java.awt.event.WindowAdapter;
36+
import java.awt.event.WindowEvent;
37+
import java.util.concurrent.CountDownLatch;
38+
import javax.imageio.ImageIO;
39+
import javax.swing.JFrame;
40+
import javax.swing.JDialog;
41+
import javax.swing.JTextArea;
42+
import javax.swing.JButton;
43+
import javax.swing.JPanel;
44+
import javax.swing.JLabel;
45+
import javax.swing.SwingUtilities;
46+
47+
public class TestTranslucentLabelText {
48+
private static Color background = new Color(0, 150, 0);
49+
private static Color foreground = new Color(255, 255, 255, 120);
50+
private static Font font = new Font("Sans Serif", Font.PLAIN, 24);
51+
private static JFrame frame;
52+
static boolean testResult;
53+
static CountDownLatch latch;
54+
private static Thread mainThread;
55+
private static boolean testPassed;
56+
private static boolean testGeneratedInterrupt;
57+
58+
private static void doTest(Runnable action) {
59+
String description
60+
= " A frame with 2 labels will be shown in middle of screen.\n"
61+
+ " Left side label text should be opaque.\n "
62+
+ " Right side label text should be translucent.\n"
63+
+ " If Right side label text is translucent, press PASS else press FAIL";
64+
65+
final JDialog dialog = new JDialog();
66+
dialog.setTitle("JLabelTranslucentTest");
67+
JTextArea textArea = new JTextArea(description);
68+
textArea.setEditable(false);
69+
final JButton testButton = new JButton("Start Test");
70+
final JButton passButton = new JButton("PASS");
71+
passButton.setEnabled(false);
72+
passButton.addActionListener((e) -> {
73+
dialog.dispose();
74+
frame.dispose();
75+
pass();
76+
});
77+
final JButton failButton = new JButton("FAIL");
78+
failButton.setEnabled(false);
79+
failButton.addActionListener((e) -> {
80+
dialog.dispose();
81+
frame.dispose();
82+
fail();
83+
});
84+
testButton.addActionListener((e) -> {
85+
testButton.setEnabled(false);
86+
action.run();
87+
passButton.setEnabled(true);
88+
failButton.setEnabled(true);
89+
});
90+
JPanel mainPanel = new JPanel(new BorderLayout());
91+
mainPanel.add(textArea, BorderLayout.CENTER);
92+
JPanel buttonPanel = new JPanel(new FlowLayout());
93+
buttonPanel.add(testButton);
94+
buttonPanel.add(passButton);
95+
buttonPanel.add(failButton);
96+
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
97+
dialog.add(mainPanel);
98+
dialog.pack();
99+
dialog.setVisible(true);
100+
dialog.addWindowListener(new WindowAdapter() {
101+
@Override
102+
public void windowClosing(WindowEvent e) {
103+
System.out.println("main dialog closing");
104+
testGeneratedInterrupt = false;
105+
frame.dispose();
106+
mainThread.interrupt();
107+
}
108+
});
109+
}
110+
111+
public static synchronized void pass() {
112+
testPassed = true;
113+
testGeneratedInterrupt = true;
114+
mainThread.interrupt();
115+
}
116+
117+
public static synchronized void fail() {
118+
testPassed = false;
119+
testGeneratedInterrupt = true;
120+
mainThread.interrupt();
121+
}
122+
123+
124+
private static JLabel create(String text)
125+
{
126+
JLabel label = new JLabel(text);
127+
label.setOpaque(true);
128+
label.setBackground(background);
129+
label.setForeground(foreground);
130+
label.setFont(font);
131+
label.setPreferredSize(new Dimension(200, 40));
132+
frame.add(label);
133+
134+
return label;
135+
}
136+
137+
private static void runTest() {
138+
frame = new JFrame();
139+
frame.setUndecorated(true);
140+
frame.setLayout(new FlowLayout());
141+
142+
//JLabel l1 = create("Test1");
143+
//JLabel opqLabel = create("<html>Test2</html>");
144+
JLabel opqLabel = create("<html><p style=\"color:rgba(255, 0, 0, 1.00)\">TestLabel</p></html>");
145+
JLabel tranLabel = create("<html><p style=\"color:rgba(255, 0, 0, 0.5)\">TestLabel</p></html>");
146+
147+
frame.pack();
148+
149+
frame.setLocationRelativeTo(null);
150+
frame.setVisible(true);
151+
frame.toFront();
152+
}
153+
154+
public static void main(String[] args) throws Exception {
155+
SwingUtilities.invokeAndWait(() -> {
156+
doTest(TestTranslucentLabelText::runTest);
157+
});
158+
mainThread = Thread.currentThread();
159+
try {
160+
Thread.sleep(180000);
161+
} catch (InterruptedException e) {
162+
if (!testPassed && testGeneratedInterrupt) {
163+
throw new RuntimeException("" +
164+
"Label HTML text does not support translucent text colors");
165+
}
166+
}
167+
if (!testGeneratedInterrupt) {
168+
throw new RuntimeException("user has not executed the test");
169+
}
170+
171+
}
172+
173+
174+
}
175+

0 commit comments

Comments
 (0)
Please sign in to comment.