From 418a82551a2c58e43963beb5aa242a58bbd30e2f Mon Sep 17 00:00:00 2001 From: Damon Nguyen Date: Tue, 2 May 2023 23:45:44 +0000 Subject: [PATCH] 8306466: Open source more AWT Drag & Drop related tests Reviewed-by: prr --- .../awt/dnd/RejectDragDropActionTest.java | 124 +++++++++++ .../awt/dnd/RemoveDragSourceListenerTest.java | 82 ++++++++ .../dnd/RemoveParentChildDropTargetTest.java | 77 +++++++ .../dnd/SameJVMModalDialogDeadlockTest.java | 193 ++++++++++++++++++ .../SkipDropCompleteTest.java | 101 +++++++++ .../dnd/SkipDropCompleteTest/SourceFrame.java | 87 ++++++++ .../dnd/SkipDropCompleteTest/TargetFrame.java | 82 ++++++++ .../TransferableObject.java | 102 +++++++++ 8 files changed, 848 insertions(+) create mode 100644 test/jdk/java/awt/dnd/RejectDragDropActionTest.java create mode 100644 test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java create mode 100644 test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java create mode 100644 test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java create mode 100644 test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java create mode 100644 test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java create mode 100644 test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java create mode 100644 test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java diff --git a/test/jdk/java/awt/dnd/RejectDragDropActionTest.java b/test/jdk/java/awt/dnd/RejectDragDropActionTest.java new file mode 100644 index 00000000000..f8d53ac45bf --- /dev/null +++ b/test/jdk/java/awt/dnd/RejectDragDropActionTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2003, 2023, 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. + */ + +/* + @test + @bug 4774532 + @summary tests that DropTargetDragEvent.getDropAction() returns correct value + after DropTargetDragEvent.rejectDrag() + @key headful + @run main RejectDragDropActionTest +*/ + +import java.awt.AWTException; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + + +public class RejectDragDropActionTest { + + private static volatile boolean incorrectActionDetected = false; + + private static final int FRAME_ACTIVATION_TIMEOUT = 3000; + + private static Frame frame; + private static DragSource ds; + private static DragGestureListener dgl; + private static DragGestureRecognizer dgr; + private final DropTargetListener dtl = new DropTargetAdapter() { + public void dragEnter(DropTargetDragEvent dtde) { + dtde.rejectDrag(); + } + public void dragOver(DropTargetDragEvent dtde) { + if (dtde.getDropAction() == DnDConstants.ACTION_NONE) { + incorrectActionDetected = true; + } + } + public void drop(DropTargetDropEvent dtde) { + dtde.rejectDrop(); + } + }; + private final DropTarget dt = new DropTarget(frame, dtl); + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + EventQueue.invokeAndWait(() -> { + frame = new Frame("RejectDragDropActionTest"); + ds = DragSource.getDefaultDragSource(); + dgl = dge -> dge.startDrag(null, new StringSelection("OOKK")); + dgr = ds.createDefaultDragGestureRecognizer(frame, DnDConstants.ACTION_COPY, dgl); + frame.setBounds(100, 100, 200, 200); + frame.setVisible(true); + }); + + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + Point startPoint = frame.getLocationOnScreen(); + Point endPoint = new Point(startPoint); + startPoint.translate(50, 50); + endPoint.translate(150, 150); + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(sign(endPoint.x - p.x), + sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(50); + } + + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + if (incorrectActionDetected) { + throw new RuntimeException("User action reported incorrectly."); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } +} diff --git a/test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java b/test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java new file mode 100644 index 00000000000..21773e43cde --- /dev/null +++ b/test/jdk/java/awt/dnd/RemoveDragSourceListenerTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2002, 2023, 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. + */ + +/* + @test + @bug 4530216 + @summary tests that DragSourceListeners are properly removed + @key headful + @run main RemoveDragSourceListenerTest +*/ + +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DragSourceMotionListener; + + +public class RemoveDragSourceListenerTest { + public static void main(String[] args) { + class TestDragSourceAdapter extends DragSourceAdapter {} + + final DragSource dragSource = DragSource.getDefaultDragSource(); + + final DragSourceAdapter listeners[] = { + new TestDragSourceAdapter(), + new TestDragSourceAdapter(), + new TestDragSourceAdapter() // should be three or more listeners + }; + + for (int i = 0; i < listeners.length; i++) { + dragSource.addDragSourceListener(listeners[i]); + } + + DragSourceListener[] dragSourceListeners = + dragSource.getDragSourceListeners(); + + if (dragSourceListeners.length != listeners.length) { + throw new RuntimeException("Unexpected length: " + + dragSourceListeners.length); + } + + for (int i = 0; i < listeners.length; i++) { + dragSource.removeDragSourceListener(listeners[i]); + } + + for (int i = 0; i < listeners.length; i++) { + dragSource.addDragSourceMotionListener(listeners[i]); + } + + DragSourceMotionListener[] dragSourceMotionListeners = + dragSource.getDragSourceMotionListeners(); + + if (dragSourceMotionListeners.length != listeners.length) { + throw new RuntimeException("Unexpected length: " + + dragSourceMotionListeners.length); + } + + for (int i = 0; i < listeners.length; i++) { + dragSource.removeDragSourceMotionListener(listeners[i]); + } + } +} diff --git a/test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java b/test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java new file mode 100644 index 00000000000..2981c8c9337 --- /dev/null +++ b/test/jdk/java/awt/dnd/RemoveParentChildDropTargetTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2001, 2023, 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. + */ + +/* + @test + @bug 4411368 + @summary tests the app doesn't crash if the child drop target is removed + after the parent drop target is removed + @key headful + @run main RemoveParentChildDropTargetTest +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.lang.reflect.InvocationTargetException; + + +public class RemoveParentChildDropTargetTest { + + static Frame frame; + static Panel panel; + static Label label; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + frame = new Frame("RemoveParentChildDropTargetTest"); + panel = new Panel(); + label = new Label("Label"); + panel.add(label); + frame.add(panel); + frame.pack(); + + panel.setDropTarget(new DropTarget(panel, new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) {} + })); + label.setDropTarget(new DropTarget(label, new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) {} + })); + panel.setDropTarget(null); + frame.setVisible(true); + + label.setDropTarget(null); + }); + + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } +} diff --git a/test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java b/test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java new file mode 100644 index 00000000000..b45ec12ac60 --- /dev/null +++ b/test/jdk/java/awt/dnd/SameJVMModalDialogDeadlockTest.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2002, 2023, 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. + */ + +/* + @test + @bug 4484572 4645584 + @summary verifies that showing a modal dialog during the drag operation + in the same JVM doesn't cause hang + @key headful + @run main SameJVMModalDialogDeadlockTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.lang.reflect.InvocationTargetException; + + +public class SameJVMModalDialogDeadlockTest implements AWTEventListener { + + Frame frame; + boolean shown = false; + boolean finished = false; + + final DragSource dragSource = DragSource.getDefaultDragSource(); + final Transferable transferable = new StringSelection("TEXT"); + final DragSourceAdapter dragSourceAdapter = new DragSourceAdapter() { + public void dragDropEnd(DragSourceDropEvent dsde) { + finished = true; + } + public void dragMouseMoved(DragSourceDragEvent dsde) { + if (shown) { + return; + } + + shown = true; + final Dialog d = new Dialog(frame, "Dialog"); + d.setModal(true); + + Runnable r1 = () -> d.setVisible(true); + new Thread(r1).start(); + } + }; + final DragGestureListener dragGestureListener = dge -> + dge.startDrag(null, transferable); + + static final Object SYNC_LOCK = new Object(); + static final int FRAME_ACTIVATION_TIMEOUT = 3000; + static final int DROP_COMPLETION_TIMEOUT = 5000; + static final int MOUSE_RELEASE_TIMEOUT = 1000; + + Component clickedComponent = null; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + SameJVMModalDialogDeadlockTest sameJVMModalDialogDeadlockTest = + new SameJVMModalDialogDeadlockTest(); + EventQueue.invokeAndWait(sameJVMModalDialogDeadlockTest::init); + sameJVMModalDialogDeadlockTest.start(); + } + + public void init() { + frame = new Frame("SameJVMModalDialogDeadlockTest"); + frame.setTitle("Test frame"); + frame.setBounds(100, 100, 200, 200); + dragSource.createDefaultDragGestureRecognizer(frame, + DnDConstants.ACTION_COPY_OR_MOVE, dragGestureListener); + + dragSource.addDragSourceMotionListener(dragSourceAdapter); + dragSource.addDragSourceListener(dragSourceAdapter); + + frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK); + frame.setVisible(true); + } + + public void start() throws AWTException, InterruptedException, + InvocationTargetException { + try { + final Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(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); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.delay(50); + } + + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(DROP_COMPLETION_TIMEOUT); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + if (!finished) { + throw new RuntimeException("DnD not completed"); + } + } + + public static 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(); + } + } + } + + boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + 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; + } +} diff --git a/test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java b/test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java new file mode 100644 index 00000000000..c3474737d5b --- /dev/null +++ b/test/jdk/java/awt/dnd/SkipDropCompleteTest/SkipDropCompleteTest.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000, 2023, 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. + */ + +/* + @test + @bug 4187912 + @summary Test that incorrectly written DnD code cannot hang the app + @key headful + @run main SkipDropCompleteTest +*/ + +import java.awt.AWTException; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + + +public class SkipDropCompleteTest { + SourceFrame sourceFrame; + TargetFrame targetFrame; + Point sourceLoc; + Point targetLoc; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + SkipDropCompleteTest skipDropCompleteTest = new SkipDropCompleteTest(); + EventQueue.invokeAndWait(skipDropCompleteTest::init); + skipDropCompleteTest.start(); + } + + public void init() { + sourceFrame = new SourceFrame(); + targetFrame = new TargetFrame(); + + sourceLoc = sourceFrame.getLocation(); + Dimension sourceSize = sourceFrame.getSize(); + sourceLoc.x += sourceSize.width / 2; + sourceLoc.y += sourceSize.height / 2; + + targetLoc = targetFrame.getLocation(); + Dimension targetSize = targetFrame.getSize(); + targetLoc.x += targetSize.width / 2; + targetLoc.y += targetSize.height / 2; + } + + public void start() throws AWTException, InterruptedException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.delay(1000); + robot.mouseMove(sourceLoc.x, sourceLoc.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (;!sourceLoc.equals(targetLoc); + sourceLoc.translate(sign(targetLoc.x - sourceLoc.x), + sign(targetLoc.y - sourceLoc.y))) { + robot.mouseMove(sourceLoc.x, sourceLoc.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } finally { + EventQueue.invokeAndWait(() -> { + if (sourceFrame != null) { + sourceFrame.dispose(); + } + if (targetFrame != null) { + targetFrame.dispose(); + } + }); + } + + System.out.println("test passed"); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } +} diff --git a/test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java b/test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java new file mode 100644 index 00000000000..2a5af985ba9 --- /dev/null +++ b/test/jdk/java/awt/dnd/SkipDropCompleteTest/SourceFrame.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000, 2023, 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.Color; +import java.awt.Frame; +import java.awt.TextArea; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class SourceFrame extends Frame + implements DragSourceListener,DragGestureListener { + + DragSource dragSource; + TransferableObject transferableObject; + TextArea textArea; + + public SourceFrame() { + + super("SkipDropCompleteTest Source Frame"); + + dragSource = new DragSource(); + textArea = new TextArea("Drag the Text from the SourceFrame\n" + + "and drop it on the TextArea in the\n" + + "Target Frame.\n" + + "Try to do some operation, like closing\n" + + "of the frame.\n"+ + "See whether the application hangs."); + add(textArea); + + dragSource.createDefaultDragGestureRecognizer(textArea, DnDConstants.ACTION_COPY, this); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + setSize(250,250); + setLocation(50,50); + setBackground(Color.red); + this.setVisible(true); + } + + public void dragEnter(DragSourceDragEvent dsde) { } + + public void dragOver(DragSourceDragEvent dsde) { } + + public void dragExit(DragSourceEvent dse) { } + + public void dropActionChanged(DragSourceDragEvent dsde ) { } + + public void dragDropEnd(DragSourceDropEvent dsde) { } + + public void dragGestureRecognized(DragGestureEvent dge) { + transferableObject = new TransferableObject(textArea.getText()); + dragSource.startDrag(dge, DragSource.DefaultCopyDrop, + transferableObject, this); + } +} diff --git a/test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java b/test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java new file mode 100644 index 00000000000..70b7bf72cb7 --- /dev/null +++ b/test/jdk/java/awt/dnd/SkipDropCompleteTest/TargetFrame.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2000, 2023, 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.Frame; +import java.awt.TextArea; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class TargetFrame extends Frame implements DropTargetListener{ + + DropTarget dropTarget; + TextArea textArea; + + public TargetFrame() { + super("SkipDropCompleteTest Target Frame"); + textArea = new TextArea(); + add(textArea); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + setSize(250,250); + setLocation(350,50); + this.setVisible(true); + + dropTarget = new DropTarget(textArea,this); + } + + public void dragEnter(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) { } + + public void dropActionChanged(DropTargetDragEvent dtde ) {} + + public void drop(DropTargetDropEvent dtde) { + try { + Transferable transferable = dtde.getTransferable(); + dtde.acceptDrop(DnDConstants.ACTION_MOVE); + + String str = (String)transferable.getTransferData(TransferableObject.stringFlavor); + textArea.setText(str); + } catch (Exception ufException ) { + ufException.printStackTrace(); + System.err.println( "Exception" + ufException.getMessage()); + dtde.rejectDrop(); + } + } +} diff --git a/test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java b/test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java new file mode 100644 index 00000000000..63592ae6fc2 --- /dev/null +++ b/test/jdk/java/awt/dnd/SkipDropCompleteTest/TransferableObject.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2000, 2023, 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.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.util.Vector; + + +public class TransferableObject implements Transferable { + private Object data; + private String stringText; + public static DataFlavor stringFlavor,localObjectFlavor; + + static + { + // Data Flavor for Java Local Object + try { + localObjectFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType); + stringFlavor = DataFlavor.stringFlavor; + } + catch (ClassNotFoundException e) { + System.out.println("Exception " + e); + } + } + + DataFlavor[] dfs; + + public TransferableObject(Object data) { + super(); + Vector v = new Vector(); + if(data instanceof String) { + v.addElement(stringFlavor); + stringText = (String)data; + } + else { + v.addElement(localObjectFlavor); + } + + dfs = new DataFlavor[v.size()]; + v.copyInto(dfs); + + this.data = data; + } + + // Retrieve the data based on the flavor + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + + System.out.println("\n ***************************************"); + System.out.println(" The Flavor passed to retrieve the data : " + + flavor.getHumanPresentableName()); + System.out.println(" The Flavors supported"); + for (int j = 0; j < dfs.length; j++) + System.out.println(" Flavor : " + dfs[j].getHumanPresentableName()); + + System.out.println(" ***************************************\n"); + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } else if (flavor.equals(stringFlavor)) { + return stringText; + } else if (localObjectFlavor.isMimeTypeEqual(flavor)) { + return data; + } + return null; + } + + public DataFlavor[] getTransferDataFlavors(){ + return dfs; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (int i = 0 ; i < dfs.length; i++) { + if (dfs[i].match(flavor)) { + return true; + } + } + return false; + } + +}