< prev index next >
test/java/awt/Window/WindowResizingOnDPIChanging/WindowResizingOnSetLocationTest.java
Print this page
@@ -19,11 +19,14 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+import java.awt.BasicStroke;
+import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
@@ -47,48 +50,54 @@
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.swing.JButton;
+import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
/* @test
- * @bug 8175293
- * @summary HiDPI (Windows): Swing components have incorrect sizes after
- * changing display resolution
+ * @bug 8175293 8176097
+ * @summary Window set location to a display with different DPI does not properly work
* @run main/manual/othervm WindowResizingOnSetLocationTest
*/
public class WindowResizingOnSetLocationTest {
private static volatile boolean testResult = false;
private static volatile CountDownLatch countDownLatch;
private static TestFrame frame;
private static JFrame mainFrame;
+ private static Rectangle[] screenBounds;
+ private static double[][] scales;
+ private static int screen1 = -1;
+ private static int screen2 = -1;
private static final String INSTRUCTIONS = "INSTRUCTIONS:\n"
+ "Verify that a window is properly resized after setting the location"
+ " to a display with different DPI.\n"
+ "\n"
+ "The test is applicable for a multi-monitor system where displays"
+ " are configured to have different DPI\n"
+ "\n"
+ "1. Press Show Frame button\n"
- + "The frame appear.\n"
+ + " (note that the button is disabled in case there are no two monitors"
+ + " with different DPI)\n"
+ + "The frame should appear in the center of the display (either"
+ + " on the first or on the second).\n"
+ "2. Check that the string \"scales [ScaleX, ScaleY]\" is painted on the window"
+ " where ScaleX and ScaleY are the scales for current display.\n"
+ "The scales are calculated as DPI / 96 and are 1 for the DPI value 96"
+ " and 2 for the DPI value 192.\n"
+ "3. Press 'Move to another display' button.\n"
+ "4. Check that the frame appears on the another display.\n"
+ "5. Check that the string \"scales [ScaleX, ScaleY]\" is updated"
+ " to show the right display scales.\n"
+ "6. Check that the window is properly resized.\n"
+ "7. Check that the window is properly repainted and does not contain drawing artifacts\n"
- + "Try different display positions (left, right, top, bottom).\n"
+ "If all tests are passed, press PASS, else press FAIL.\n";
public static void main(String args[]) throws Exception {
countDownLatch = new CountDownLatch(1);
@@ -99,31 +108,35 @@
}
}
private static void createUI() {
+ initScreenBounds();
+
mainFrame = new JFrame("DPI change test");
GridBagLayout layout = new GridBagLayout();
JPanel mainControlPanel = new JPanel(layout);
JPanel resultButtonPanel = new JPanel(layout);
GridBagConstraints gbc = new GridBagConstraints();
- JPanel testPanel = new JPanel(new FlowLayout());
+ JPanel testPanel = new JPanel(new BorderLayout());
JButton frameButton = new JButton("Show Frame");
frameButton.addActionListener((e) -> {
- int x = 20;
- int y = 10;
- int w = 400;
- int h = 300;
+ GraphicsConfiguration gc = GraphicsEnvironment
+ .getLocalGraphicsEnvironment()
+ .getScreenDevices()[screen1]
+ .getDefaultConfiguration();
- frame = new TestFrame(w, h);
- frame.setLocation(x, y);
+ Rectangle rect = getCenterRect(screenBounds[screen2]);
+ frame = new TestFrame(gc, rect);
frame.setVisible(true);
});
- testPanel.add(frameButton);
+ frameButton.setEnabled(screen1 != -1 && screen2 != -1);
+ testPanel.add(getDisplaysComponent(), BorderLayout.CENTER);
+ testPanel.add(frameButton, BorderLayout.SOUTH);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
mainControlPanel.add(testPanel, gbc);
@@ -191,18 +204,103 @@
if (mainFrame != null && mainFrame.isVisible()) {
mainFrame.dispose();
}
}
+ static void initScreenBounds() {
+
+ GraphicsDevice[] devices = GraphicsEnvironment
+ .getLocalGraphicsEnvironment()
+ .getScreenDevices();
+
+ screenBounds = new Rectangle[devices.length];
+ scales = new double[devices.length][2];
+ for (int i = 0; i < devices.length; i++) {
+ GraphicsConfiguration gc = devices[i].getDefaultConfiguration();
+ screenBounds[i] = gc.getBounds();
+ AffineTransform tx = gc.getDefaultTransform();
+ scales[i][0] = tx.getScaleX();
+ scales[i][1] = tx.getScaleY();
+ }
+
+ for (int i = 0; i < devices.length; i++) {
+ for (int j = i + 1; j < devices.length; j++) {
+ if (scales[i][0] != scales[j][0] || scales[i][1] != scales[j][1]) {
+ screen1 = i;
+ screen2 = j;
+ }
+ }
+ }
+ }
+
+ private static Rectangle getCenterRect(Rectangle rect) {
+ int w = rect.width / 2;
+ int h = rect.height / 2;
+ int x = rect.x + w / 2;
+ int y = rect.y + h / 2;
+
+ return new Rectangle(x, y, w, h);
+ }
+
+ static JComponent getDisplaysComponent() {
+
+ Rectangle rect = screenBounds[0];
+ for (int i = 0; i < screenBounds.length; i++) {
+ rect = rect.union(screenBounds[i]);
+ }
+
+ final BufferedImage img = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = img.createGraphics();
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, rect.width, rect.height);
+ g.translate(-rect.x, -rect.y);
+
+ g.setStroke(new BasicStroke(8f));
+ for (int i = 0; i < screenBounds.length; i++) {
+ Rectangle r = screenBounds[i];
+ g.setColor(Color.BLACK);
+ g.drawRect(r.x, r.y, r.width, r.height);
+
+ g.setColor(Color.ORANGE);
+ Rectangle cr = getCenterRect(r);
+ g.fillRect(cr.x, cr.y, cr.width, cr.height);
+
+ double scaleX = scales[i][0];
+ double scaleY = scales[i][1];
+ float fontSize = rect.height / 7;
+ g.setFont(g.getFont().deriveFont(fontSize));
+ g.setColor(Color.BLUE);
+ g.drawString(String.format("Scale: [%2.1f, %2.1f]", scaleX, scaleY),
+ r.x + r.width / 8, r.y + r.height / 2);
+
+ }
+
+ g.dispose();
+
+ JPanel panel = new JPanel() {
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
+
+ }
+ };
+
+ panel.setPreferredSize(new Dimension(400, 200));
+
+ return panel;
+ }
+
static class TestFrame extends JFrame {
private final TestMultiResolutionImage mrImage;
- public TestFrame(int width, int height) throws HeadlessException {
- super("Test Frame");
- setSize(width, height);
- mrImage = new TestMultiResolutionImage(width, height);
+ public TestFrame(GraphicsConfiguration gc, Rectangle rect) throws HeadlessException {
+ super(gc);
+ setBounds(rect);
+ mrImage = new TestMultiResolutionImage(rect.width, rect.height);
JPanel panel = new JPanel(new FlowLayout()) {
@Override
public void paint(Graphics g) {
super.paint(g);
@@ -215,33 +313,21 @@
};
JButton button = new JButton("Move to another display");
button.addActionListener((e) -> {
GraphicsConfiguration config = getGraphicsConfiguration();
- GraphicsDevice device = config.getDevice();
GraphicsDevice[] devices = GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getScreenDevices();
- boolean found = false;
- for (GraphicsDevice dev : devices) {
- if (!dev.equals(device)) {
- found = true;
- Rectangle bounds = dev.getDefaultConfiguration().getBounds();
-
- AffineTransform tx = config.getDefaultTransform();
- int x = (int) Math.round(bounds.x / tx.getScaleX()) + 15;
- int y = (int) Math.round(bounds.y / tx.getScaleY()) + 15;
- frame.setLocation(x, y);
- break;
- }
- }
- if (!found) {
- System.out.println("Another display not found!");
- }
+ int index = devices[screen1].getDefaultConfiguration().equals(config)
+ ? screen2 : screen1;
+
+ Rectangle r = getCenterRect(screenBounds[index]);
+ frame.setBounds(r);
});
panel.add(button);
add(panel);
}
< prev index next >