8160248: Dragged internal frame leaves artifacts for floating point ui scale
authoralexsch
Tue, 05 Jul 2016 09:48:49 +0300
changeset 39555 5cf973a23925
parent 39554 12687019f2b9
child 39556 50963eeaefca
8160248: Dragged internal frame leaves artifacts for floating point ui scale Reviewed-by: ssadetsky
jdk/src/java.desktop/share/classes/javax/swing/JComponent.java
jdk/test/javax/swing/JInternalFrame/8160248/JInternalFrameDraggingTest.java
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java	Tue Jul 05 09:36:41 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java	Tue Jul 05 09:48:49 2016 +0300
@@ -844,9 +844,10 @@
                     Rectangle cr;
 
                     cr = comp.getBounds(tmpRect);
-
-                    boolean hitClip = g.hitClip(cr.x, cr.y, cr.width,
-                                                cr.height);
+                    Shape clip = g.getClip();
+                    boolean hitClip = (clip != null)
+                            ? clip.intersects(cr.x, cr.y, cr.width, cr.height)
+                            : true;
 
                     if (hitClip) {
                         if (checkSiblings && i > 0) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/8160248/JInternalFrameDraggingTest.java	Tue Jul 05 09:48:49 2016 +0300
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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.BorderLayout;
+import java.awt.Color;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.image.BufferedImage;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @bug 8160248 8160332
+ * @summary Dragged internal frame leaves artifacts for floating point ui scale
+ * @run main/othervm -Dsun.java2d.uiScale=1.2 JInternalFrameDraggingTest
+ * @run main/othervm -Dsun.java2d.uiScale=1.5 JInternalFrameDraggingTest
+ * @run main/othervm -Dsun.java2d.uiScale=1 JInternalFrameDraggingTest
+ * @run main/othervm -Dsun.java2d.uiScale=2.5 JInternalFrameDraggingTest
+ */
+public class JInternalFrameDraggingTest {
+
+    private static JFrame frame;
+    private static JDesktopPane desktopPane;
+    private static JInternalFrame internalFrame;
+    private static int FRAME_SIZE = 500;
+    private static Color BACKGROUND_COLOR = Color.ORANGE;
+
+    public static void main(String[] args) throws Exception {
+
+        Robot robot = new Robot();
+        robot.setAutoDelay(20);
+        SwingUtilities.invokeAndWait(JInternalFrameDraggingTest::createAndShowGUI);
+        robot.waitForIdle();
+
+        final int translate = FRAME_SIZE / 4;
+        moveFrame(robot, translate, translate / 2, translate / 2);
+        robot.waitForIdle();
+
+        Point p = getDesktopPaneLocation();
+        int size = translate / 2;
+        Rectangle rect = new Rectangle(p.x, p.y, size, size);
+        BufferedImage img = robot.createScreenCapture(rect);
+
+        int testRGB = BACKGROUND_COLOR.getRGB();
+        for (int i = 0; i < size; i++) {
+            int rgbCW = img.getRGB(i, size / 2);
+            int rgbCH = img.getRGB(size / 2, i);
+            if (rgbCW != testRGB || rgbCH != testRGB) {
+                throw new RuntimeException("Background color is wrong!");
+            }
+        }
+    }
+
+    private static void createAndShowGUI() {
+
+        frame = new JFrame();
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        frame.setLayout(new BorderLayout());
+
+        desktopPane = new JDesktopPane();
+        desktopPane.setBackground(BACKGROUND_COLOR);
+
+        frame.add(desktopPane, BorderLayout.CENTER);
+        frame.setSize(FRAME_SIZE, FRAME_SIZE);
+        frame.setVisible(true);
+
+        internalFrame = new JInternalFrame("Test");
+        internalFrame.setSize(FRAME_SIZE / 2, FRAME_SIZE / 2);
+        desktopPane.add(internalFrame);
+        internalFrame.setVisible(true);
+        internalFrame.setResizable(true);
+
+        frame.setVisible(true);
+    }
+
+    private static void moveFrame(Robot robot, int w, int h, int N) throws Exception {
+        Point p = getInternalFrameLocation();
+        int xs = p.x + 100;
+        int ys = p.y + 15;
+        robot.mouseMove(xs, ys);
+        try {
+            robot.mousePress(InputEvent.BUTTON1_MASK);
+
+            int dx = w / N;
+            int dy = h / N;
+
+            int y = ys;
+            for (int x = xs; x < xs + w; x += dx, y += dy) {
+                robot.mouseMove(x, y);
+            }
+        } finally {
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        }
+    }
+
+    private static Point getInternalFrameLocation() throws Exception {
+        final Point[] points = new Point[1];
+        SwingUtilities.invokeAndWait(() -> {
+            points[0] = internalFrame.getLocationOnScreen();
+        });
+        return points[0];
+    }
+
+    private static Point getDesktopPaneLocation() throws Exception {
+        final Point[] points = new Point[1];
+        SwingUtilities.invokeAndWait(() -> {
+            points[0] = desktopPane.getLocationOnScreen();
+        });
+        return points[0];
+    }
+}