Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8224261: JProgressBar always with border painted around it #16467

Closed
wants to merge 7 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 37 additions & 90 deletions test/jdk/javax/swing/JProgressBar/TestProgressBarBorder.java
Original file line number Diff line number Diff line change
@@ -25,86 +25,53 @@
* @test
* @bug 8224261
* @key headful
* @summary Verifies if JProgressBar border is painted even though border
* @library ../regtesthelpers
* @build Util
* @summary Verifies JProgressBar border is not painted when border
* painting is set to false
* @run main TestProgressBarBorder
*/

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComponent;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestProgressBarBorder {
import static java.awt.image.BufferedImage.TYPE_INT_RGB;

private static JFrame frame;
public class TestProgressBarBorder {
private static JProgressBar progressBar;
private static volatile Point pt;
private static volatile boolean passed;
private static volatile boolean isImgSame;
private static BufferedImage borderPaintedImg;
private static BufferedImage borderNotPaintedImg;

public static void main(String[] args) throws Exception {
for (UIManager.LookAndFeelInfo laf :
UIManager.getInstalledLookAndFeels()) {
if (laf.getName().contains("Nimbus") || laf.getName().contains("GTK")) {
System.out.println("Testing LAF: " + laf.getName());
SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf));
} else {
if (!laf.getName().contains("Nimbus") && !laf.getName().contains("GTK")) {
continue;
}
Robot robot = new Robot();
robot.setAutoDelay(100);
try {
SwingUtilities.invokeAndWait(() -> {
createAndShowUI();
});

robot.waitForIdle();
robot.delay(1000);

SwingUtilities.invokeAndWait(() -> {
pt = progressBar.getLocationOnScreen();
});

BufferedImage borderPaintedImg =
robot.createScreenCapture(new Rectangle(pt.x, pt.y,
progressBar.getWidth(), progressBar.getHeight()));

progressBar.setBorderPainted(false);
robot.waitForIdle();
robot.delay(500);

BufferedImage borderNotPaintedImg =
robot.createScreenCapture(new Rectangle(pt.x, pt.y,
progressBar.getWidth(), progressBar.getHeight()));

robot.delay(500);

SwingUtilities.invokeAndWait(() -> {
passed = compareImage(borderPaintedImg, borderNotPaintedImg);
});

if (!passed) {
ImageIO.write(borderPaintedImg, "png", new File("borderPaintedImg.png"));
ImageIO.write(borderNotPaintedImg, "png", new File("borderNotPaintedImg.png"));
throw new RuntimeException("JProgressBar border is painted although " +
"border painting is set to false");
}
} finally {
SwingUtilities.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
System.out.println("Testing LAF: " + laf.getName());
SwingUtilities.invokeAndWait(() -> {
setLookAndFeel(laf);
createAndShowUI();
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do everything on EDT or don't bother with EDT: mixing it in this way isn't good.

In this case, it's safe to call the methods you use on the main thread. However, I heard that there's a convention to run all the code on EDT. Whatever you choose… but at least don't mix the threads.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.


borderPaintedImg = paintToImage(progressBar);
progressBar.setBorderPainted(false);
borderNotPaintedImg = paintToImage(progressBar);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to call progressBar.setBorderPainted(true) explicitly—this way the test will not depend on the default value. If whatever reason the default value changes, the test will become useless… it will be testing with isBorderPainted == false in both cases.
You're setting it in createAndShowUI; I still think it's better to move the call to progressBar.setBorderPainted(true) here.

Aren't withBorder and withoutBorder more succinct names?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

isImgSame = Util.compareBufferedImages(borderPaintedImg, borderNotPaintedImg);

if (isImgSame) {
ImageIO.write(borderPaintedImg, "png", new File("borderPaintedImg.png"));
ImageIO.write(borderNotPaintedImg, "png", new File("borderNotPaintedImg.png"));
throw new RuntimeException("JProgressBar border is painted when border\n" +
" painting is set to false");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new RuntimeException("JProgressBar border is painted when border\n" +
" painting is set to false");
throw new RuntimeException("JProgressBar border is painted when border " +
"painting is set to false");

You should probably remove the line break from the error message.

}
}
}
@@ -121,40 +88,20 @@ private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) {
}

private static void createAndShowUI() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't show the UI anymore, createProgressBar or initProgressBar will be a better name.

frame = new JFrame("Test JProgressBar Border");
JPanel p = new JPanel(new FlowLayout());
progressBar = new JProgressBar();
progressBar = new JProgressBar();
progressBar.setSize(100,50);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
progressBar.setSize(100,50);
progressBar.setSize(100, 50);

// set initial value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is redundant, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah.. updated.

progressBar.setValue(0);
progressBar.setBorderPainted(true);
progressBar.setStringPainted(true);
p.add(progressBar);
frame.add(p);
frame.setSize(200, 100);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}

/*
* Compare JProgressBar border painted and border not painted image and
* if both images width and height are equal but pixel's RGB values are
* not equal, method returns true; false otherwise.
*/

private static boolean compareImage(BufferedImage img1, BufferedImage img2) {
if (img1.getWidth() == img2.getWidth()
&& img1.getHeight() == img2.getHeight()) {
for (int x = 0; x < img1.getWidth(); ++x) {
for (int y = 0; y < img1.getHeight(); ++y) {
if (img1.getRGB(x, y) != img2.getRGB(x, y)) {
return true;
}
}
}
return false;
} else {
return false;
}
private static BufferedImage paintToImage(JComponent content) {
BufferedImage im = new BufferedImage(content.getWidth(), content.getHeight(),
TYPE_INT_RGB);
Graphics g = im.getGraphics();
content.paint(g);
g.dispose();
return im;
}
}