Skip to content

Commit 51cce6e

Browse files
committedJan 29, 2025
8318577: Windows Look-and-Feel JProgressBarUI does not render correctly on 2x UI scale
Reviewed-by: tr
1 parent 6bfae3a commit 51cce6e

File tree

2 files changed

+113
-10
lines changed

2 files changed

+113
-10
lines changed
 

‎src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
3333
import java.awt.Graphics2D;
3434
import java.awt.Insets;
3535
import java.awt.Rectangle;
36+
import java.awt.geom.AffineTransform;
3637

3738
import javax.swing.JComponent;
3839
import javax.swing.JProgressBar;
@@ -128,38 +129,43 @@ protected void paintDeterminate(Graphics g, JComponent c) {
128129
if (xp != null) {
129130
boolean vertical = (progressBar.getOrientation() == JProgressBar.VERTICAL);
130131
boolean isLeftToRight = WindowsGraphicsUtils.isLeftToRight(c);
131-
int barRectWidth = progressBar.getWidth();
132-
int barRectHeight = progressBar.getHeight()-1;
132+
Graphics2D g2 = (Graphics2D) g;
133+
AffineTransform at = g2.getTransform();
134+
double scaleX = at.getScaleX();
135+
double scaleY = at.getScaleY();
136+
137+
int barRectWidth = (int)Math.ceil(progressBar.getWidth() * scaleX);
138+
int barRectHeight = (int)Math.ceil(progressBar.getHeight() * scaleY);
139+
133140
// amount of progress to draw
134-
int amountFull = getAmountFull(null, barRectWidth, barRectHeight);
141+
int amountFull = (int)(getAmountFull(null, barRectWidth, barRectHeight) / scaleX);
135142

136143
paintXPBackground(g, vertical, barRectWidth, barRectHeight);
144+
137145
// Paint progress
138146
if (progressBar.isStringPainted()) {
139147
// Do not paint the standard stripes from the skin, because they obscure
140148
// the text
141149
g.setColor(progressBar.getForeground());
142-
barRectHeight -= 2;
143-
barRectWidth -= 2;
144150

145151
if (barRectWidth <= 0 || barRectHeight <= 0) {
146152
return;
147153
}
148154

149-
Graphics2D g2 = (Graphics2D)g;
150155
g2.setStroke(new BasicStroke((float)(vertical ? barRectWidth : barRectHeight),
151156
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
152157
if (!vertical) {
153158
if (isLeftToRight) {
154-
g2.drawLine(2, barRectHeight / 2 + 1,
155-
amountFull - 2, barRectHeight / 2 + 1);
159+
g2.drawLine(0, barRectHeight / 2,
160+
amountFull, barRectHeight / 2);
156161
} else {
157162
g2.drawLine(2 + barRectWidth,
158163
barRectHeight / 2 + 1,
159164
2 + barRectWidth - (amountFull - 2),
160165
barRectHeight / 2 + 1);
161166
}
162-
paintString(g, 0, 0, barRectWidth, barRectHeight, amountFull, null);
167+
paintString(g, 0, 0, (int)(barRectWidth / scaleX),
168+
(int)(barRectHeight / scaleY), amountFull, null);
163169
} else {
164170
g2.drawLine(barRectWidth/2 + 1, barRectHeight + 1,
165171
barRectWidth/2 + 1, barRectHeight + 1 - amountFull + 2);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright (c) 2025, 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+
/*
25+
* @test
26+
* @bug 8318577
27+
* @summary Tests JProgressBarUI renders correctly in Windows L&F
28+
* @requires (os.family == "windows")
29+
* @library /java/awt/regtesthelpers
30+
* @build PassFailJFrame
31+
* @run main/manual TestProgressBarUI
32+
*/
33+
34+
import java.awt.BorderLayout;
35+
import java.awt.Color;
36+
import java.awt.Dimension;
37+
import java.awt.FlowLayout;
38+
39+
import javax.swing.JComponent;
40+
import javax.swing.JFrame;
41+
import javax.swing.JPanel;
42+
import javax.swing.JProgressBar;
43+
import javax.swing.SwingUtilities;
44+
import javax.swing.UIManager;
45+
46+
public class TestProgressBarUI {
47+
48+
private static final String instructionsText = """
49+
Two progressbar "Good" and "Bad"
50+
will be shown with different preferred size,
51+
If the "Bad" progressbar is rendered at the same
52+
height as "Good" progressbar,
53+
without any difference in padding internally
54+
the test passes, otherwise fails. """;
55+
56+
public static void main(String[] args) throws Exception {
57+
System.setProperty("sun.java2d.uiScale", "2.0");
58+
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
59+
PassFailJFrame.builder()
60+
.title("ProgressBar Instructions")
61+
.instructions(instructionsText)
62+
.rows(9)
63+
.columns(36)
64+
.testUI(TestProgressBarUI::doTest)
65+
.build()
66+
.awaitAndCheck();
67+
}
68+
69+
public static JFrame doTest() {
70+
JFrame frame = new JFrame("JProgressBar");
71+
72+
JPanel panel = new JPanel(new FlowLayout(20, 20, FlowLayout.LEADING));
73+
panel.setBackground(Color.white);
74+
75+
JProgressBar p1 = new JProgressBar(0, 100);
76+
p1.setValue(50);
77+
p1.setStringPainted(true);
78+
p1.setString("GOOD");
79+
p1.setPreferredSize(new Dimension(100, 21));
80+
panel.add(p1);
81+
82+
JProgressBar p2 = new JProgressBar(0, 100);
83+
p2.setValue(50);
84+
p2.setStringPainted(true);
85+
p2.setString("BAD");
86+
87+
p2.setPreferredSize(new Dimension(100, 22));
88+
panel.add(p2);
89+
90+
JComponent c = (JComponent) frame.getContentPane();
91+
c.add(panel, BorderLayout.CENTER);
92+
93+
frame.pack();
94+
frame.setLocationByPlatform(true);
95+
return frame;
96+
}
97+
}

0 commit comments

Comments
 (0)
Please sign in to comment.