-
Bug
-
Resolution: Unresolved
-
P3
-
8, 11, 17, 21, 22
-
x86_64
-
windows_10
ADDITIONAL SYSTEM INFORMATION :
Java 17 / 21 on Windows 10 / 11
A DESCRIPTION OF THE PROBLEM :
JProgressBar (StringPainted variant) does not render consistently on HiDPI displays (e.g. 200% Scale Factor) on Windows (using Windows Look-and-Feel) depending on the height at which JProgressBar is rendered. Possibly a rounding issue. The issue only occurs when the JProgressBar is rendered at 2x scale when the JProgressBar height is even. There will be a 0px padding on the top but a 2px padding at the bottom, making the JProgressBar looks visibly off.
Here is a screenshot:
<link>
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the example code on Windows with 200% Scale Factor (or with --def sun.java2d.uiScale=2) and compare two identical JProgressBar components looking different when rendered with different component heights.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JProgressBar should look good and render consistently.
ACTUAL -
JProgressBar resize (e.g. when resizing a window) results in a white line flicking in and out of existence because JProgressBar does not render consistently.
---------- BEGIN SOURCE ----------
package test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
JFrame frame = new JFrame("JProgressBar");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JPanel panel = new JPanel(new FlowLayout(20, 20, FlowLayout.LEADING));
panel.setBackground(Color.white);
JProgressBar p1 = new JProgressBar(0, 100);
p1.setValue(100);
p1.setStringPainted(true);
p1.setString("GOOD");
p1.setPreferredSize(new Dimension(100, 21));
panel.add(p1);
JProgressBar p2 = new JProgressBar(0, 100);
p2.setValue(100);
p2.setStringPainted(true);
p2.setString("BAD");
p2.setPreferredSize(new Dimension(100, 22));
panel.add(p2);
JComponent c = (JComponent) frame.getContentPane();
c.add(panel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not found a workaround.
FREQUENCY : always
Java 17 / 21 on Windows 10 / 11
A DESCRIPTION OF THE PROBLEM :
JProgressBar (StringPainted variant) does not render consistently on HiDPI displays (e.g. 200% Scale Factor) on Windows (using Windows Look-and-Feel) depending on the height at which JProgressBar is rendered. Possibly a rounding issue. The issue only occurs when the JProgressBar is rendered at 2x scale when the JProgressBar height is even. There will be a 0px padding on the top but a 2px padding at the bottom, making the JProgressBar looks visibly off.
Here is a screenshot:
<link>
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the example code on Windows with 200% Scale Factor (or with --def sun.java2d.uiScale=2) and compare two identical JProgressBar components looking different when rendered with different component heights.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JProgressBar should look good and render consistently.
ACTUAL -
JProgressBar resize (e.g. when resizing a window) results in a white line flicking in and out of existence because JProgressBar does not render consistently.
---------- BEGIN SOURCE ----------
package test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
JFrame frame = new JFrame("JProgressBar");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JPanel panel = new JPanel(new FlowLayout(20, 20, FlowLayout.LEADING));
panel.setBackground(Color.white);
JProgressBar p1 = new JProgressBar(0, 100);
p1.setValue(100);
p1.setStringPainted(true);
p1.setString("GOOD");
p1.setPreferredSize(new Dimension(100, 21));
panel.add(p1);
JProgressBar p2 = new JProgressBar(0, 100);
p2.setValue(100);
p2.setStringPainted(true);
p2.setString("BAD");
p2.setPreferredSize(new Dimension(100, 22));
panel.add(p2);
JComponent c = (JComponent) frame.getContentPane();
c.add(panel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not found a workaround.
FREQUENCY : always