/** * @test * @key headful * @bug 4494085 8158366 * @summary verifies that the recognized action matches modifiers state * @compile RecognizedActionTest.java * @run main RecognizedActionTest */ import java.awt.Frame; import java.awt.Component; import java.awt.Robot; import java.awt.Point; import java.awt.Dimension; import java.awt.AWTEvent; import java.awt.event.AWTEventListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragSource; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureEvent; public class RecognizedActionTest implements AWTEventListener { final Frame frame = new Frame(); boolean dragGestureRecognized = false; int currentDragAction = DnDConstants.ACTION_NONE; final int[] modifiers = { 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK }; final DragSource dragSource = DragSource.getDefaultDragSource(); final DragGestureListener dragGestureListener = new DragGestureListener() { public void dragGestureRecognized(DragGestureEvent dge) { dragGestureRecognized = true; if (dge.getDragAction() != currentDragAction) { throw new RuntimeException("Expected: " + Integer.toHexString(currentDragAction) + " recognized: " + Integer.toHexString(dge.getDragAction())); } } }; final Object SYNC_LOCK = new Object(); final int FRAME_ACTIVATION_TIMEOUT = 2000; final int MOUSE_RELEASE_TIMEOUT = 1000; Component clickedComponent = null; public void init() { try { frame.setTitle("Test frame"); frame.setBounds(100, 100, 200, 200); dragSource.createDefaultDragGestureRecognizer(frame, DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK, dragGestureListener); frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK); frame.setVisible(true); Thread.sleep(100); final Robot robot = new Robot(); robot.waitForIdle(); Thread.sleep(FRAME_ACTIVATION_TIMEOUT); final Point srcPoint = frame.getLocationOnScreen(); Dimension d = frame.getSize(); srcPoint.translate(d.width / 2, d.height / 2); if (!pointInComponent(robot, srcPoint, frame)) { System.err.println("WARNING: Couldn't locate source frame."); return; } final Point dstPoint = new Point(srcPoint); dstPoint.translate(d.width / 4, d.height / 4); if (!pointInComponent(robot, dstPoint, frame)) { System.err.println("WARNING: Couldn't locate target frame."); return; } for (int i = 0; i < modifiers.length; i++) { currentDragAction = convertModifiersToDropAction(modifiers[i]); dragGestureRecognized = false; final Point curPoint = new Point(srcPoint); robot.mouseMove(curPoint.x, curPoint.y); switch (modifiers[i]) { case InputEvent.SHIFT_DOWN_MASK: robot.keyPress(KeyEvent.VK_SHIFT); robot.waitForIdle(); break; case InputEvent.CTRL_DOWN_MASK: robot.keyPress(KeyEvent.VK_CONTROL); robot.waitForIdle(); break; case InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK: robot.keyPress(KeyEvent.VK_CONTROL); robot.waitForIdle(); robot.keyPress(KeyEvent.VK_SHIFT); robot.waitForIdle(); break; default: break; } robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); Thread.sleep(100); for (; !curPoint.equals(dstPoint) && !dragGestureRecognized; curPoint.translate(sign(dstPoint.x - curPoint.x), sign(dstPoint.y - curPoint.y))) { robot.mouseMove(curPoint.x, curPoint.y); Thread.sleep(50); } Thread.sleep(100); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); switch (modifiers[i]) { case InputEvent.SHIFT_DOWN_MASK: robot.keyRelease(KeyEvent.VK_SHIFT); robot.waitForIdle(); break; case InputEvent.CTRL_DOWN_MASK: robot.keyRelease(KeyEvent.VK_CONTROL); robot.waitForIdle(); break; case InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK: robot.keyRelease(KeyEvent.VK_CONTROL); robot.waitForIdle(); robot.keyRelease(KeyEvent.VK_SHIFT); robot.waitForIdle(); break; default: break; } Thread.sleep(100); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("The test failed."); } } public int sign(int n) { return n < 0 ? -1 : n == 0 ? 0 : 1; } public void reset() { clickedComponent = null; } public void eventDispatched(AWTEvent e) { if (e.getID() == MouseEvent.MOUSE_RELEASED) { clickedComponent = (Component) e.getSource(); synchronized (SYNC_LOCK) { SYNC_LOCK.notifyAll(); } } } public boolean pointInComponent(Robot robot, Point p, Component comp) throws InterruptedException { reset(); robot.mouseMove(p.x, p.y); robot.waitForIdle(); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.waitForIdle(); synchronized (SYNC_LOCK) { robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); } Component c = clickedComponent; while (c != null && c != comp) { c = c.getParent(); } return c == comp; } public void dispose() { frame.dispose(); } public int convertModifiersToDropAction(int modifiers) { int dropAction = DnDConstants.ACTION_NONE; switch (modifiers & (InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) { case InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK: dropAction = DnDConstants.ACTION_LINK; break; case InputEvent.CTRL_DOWN_MASK: dropAction = DnDConstants.ACTION_COPY; break; case InputEvent.SHIFT_DOWN_MASK: dropAction = DnDConstants.ACTION_MOVE; break; default: dropAction = DnDConstants.ACTION_MOVE; break; } return dropAction; } public static void main(String args[]) { RecognizedActionTest actionTest = new RecognizedActionTest(); actionTest.init(); actionTest.dispose(); } }