1 /* 2 * Copyright (c) 2017, 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 * @key headful 27 * @bug 8159062 28 * @summary Tests DnD property with HIDPI scale set to non-interger value 2.5 29 * @run main/othervm -Dsun.java2d.uiScale=2.5 DragTestWithHIDPI 30 */ 31 32 import javax.swing.JList; 33 import javax.swing.TransferHandler; 34 import javax.swing.JFrame; 35 import javax.swing.JComponent; 36 import javax.swing.SwingUtilities; 37 38 import java.awt.Robot; 39 import java.awt.BorderLayout; 40 import java.awt.Point; 41 import java.awt.Dimension; 42 import java.awt.MouseInfo; 43 import java.awt.event.InputEvent; 44 45 public class DragTestWithHIDPI extends TransferHandler { 46 47 private static boolean didDrag = false; 48 private static int threshold = 10; 49 private static int DEFAULT_DELAY = 550; 50 51 private Robot robot = null; 52 private static JList list = null; 53 private static Point listLocation = null; 54 private static Dimension listSize = null; 55 private static JFrame f = null; 56 57 private enum Direction { 58 RIGHT, LEFT, BOTTOM, TOP 59 } 60 main(String[] args)61 public static void main(String[] args) throws Exception { 62 DragTestWithHIDPI test = new DragTestWithHIDPI(); 63 64 // set the mouse move drag threshold 65 System.setProperty("awt.dnd.drag.threshold", String.valueOf(threshold)); 66 67 test.createGUI(); 68 test.doTest(); 69 System.out.println("Test Passed"); 70 test.disposeGUI(); 71 } 72 exportAsDrag(JComponent comp, InputEvent e, int action)73 public void exportAsDrag(JComponent comp, InputEvent e, int action) { 74 didDrag = true; 75 } 76 DragTestWithHIDPI()77 public DragTestWithHIDPI() { 78 super("foreground"); 79 } 80 createGUI()81 private void createGUI() throws Exception{ 82 SwingUtilities.invokeAndWait(() -> { 83 String[] listData = 84 new String[]{"Pacific Ocean", "Atlantic Ocean", "Indian Ocean", 85 "Arctic Ocean"}; 86 list = new JList(listData); 87 list.setDragEnabled(true); 88 list.setTransferHandler(new DragTestWithHIDPI()); 89 90 f = new JFrame("DragTestWithHIDPI"); 91 f.getContentPane().add(list, BorderLayout.CENTER); 92 f.pack(); 93 f.toFront(); 94 f.setVisible(true); 95 96 listLocation = list.getLocationOnScreen(); 97 listSize = list.getSize(); 98 }); 99 } 100 disposeGUI()101 private void disposeGUI () throws Exception { 102 SwingUtilities.invokeAndWait(() -> { 103 f.dispose(); 104 }); 105 } 106 doTest()107 private void doTest() throws Exception { 108 109 robot = new Robot(); 110 robot.waitForIdle(); 111 112 for (Direction direction : Direction.values()) { 113 //Drag should not start only by moving (threshold - 1) pixels 114 didDrag = false; 115 test(threshold - 1, direction); 116 if (didDrag) { 117 disposeGUI(); 118 throw new RuntimeException( 119 "Shouldn't start drag until > " + threshold + 120 " pixels " + " while moving " + direction); 121 } 122 123 // Drag should not start only by moving threshold pixels 124 didDrag = false; 125 test(threshold, direction); 126 if (didDrag) { 127 disposeGUI(); 128 throw new RuntimeException( 129 "Shouldn't start drag until > " + threshold + 130 " pixels" + " while moving " + direction); 131 } 132 133 // Drag should start after moving threshold + 1 pixel 134 didDrag = false; 135 test(threshold + 1, direction); 136 if (!didDrag) { 137 disposeGUI(); 138 throw new RuntimeException( 139 "Should start drag after > " + threshold + " pixels" + 140 " while moving " + direction); 141 } 142 } 143 } 144 test(int threshold, Direction direction)145 private void test(int threshold, Direction direction) { 146 clickMouseOnList(InputEvent.BUTTON1_DOWN_MASK); 147 Point p = MouseInfo.getPointerInfo().getLocation(); 148 robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); 149 robot.delay(DEFAULT_DELAY); 150 glide(p, direction, threshold); 151 robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); 152 } 153 glide(Point p, Direction direction, int toAdd)154 private void glide(Point p, Direction direction, int toAdd) { 155 switch (direction) { 156 case RIGHT: 157 // move towards right 158 glide(p.x, p.y, p.x + toAdd, p.y); 159 break; 160 case LEFT: 161 // move towards left 162 glide(p.x, p.y, p.x - toAdd, p.y); 163 break; 164 case BOTTOM: 165 // move towards bottom 166 glide(p.x, p.y, p.x, p.y + toAdd); 167 break; 168 case TOP: 169 // move towards top 170 glide(p.x, p.y, p.x, p.y - toAdd); 171 break; 172 173 } 174 } 175 176 /* 177 Some utilities functions from JRobot class. 178 */ moveMouseToList()179 private void moveMouseToList() { 180 int x = listLocation.x + listSize.width/2; 181 int y = listLocation.y + listSize.height/2; 182 robot.mouseMove(x, y); 183 robot.delay(DEFAULT_DELAY); 184 } 185 clickMouse(int buttons)186 private void clickMouse(int buttons) { 187 robot.mousePress(buttons); 188 robot.mouseRelease(buttons); 189 robot.delay(DEFAULT_DELAY); 190 } 191 clickMouseOnList(int buttons)192 private void clickMouseOnList(int buttons) { 193 moveMouseToList(); 194 clickMouse(buttons); 195 } 196 glide(int x0, int y0, int x1, int y1)197 private void glide(int x0, int y0, int x1, int y1) { 198 float dmax = (float)Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0)); 199 float dx = (x1 - x0) / dmax; 200 float dy = (y1 - y0) / dmax; 201 202 robot.mouseMove(x0, y0); 203 for (int i=1; i<=dmax; i++) { 204 robot.mouseMove((int)(x0 + dx*i), (int)(y0 + dy*i)); 205 } 206 robot.delay(DEFAULT_DELAY); 207 } 208 } 209 210