Path: blob/master/test/jdk/sun/awt/dnd/8024061/bug8024061.java
41153 views
/*1* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @key headful26* @bug 802406127* @summary Checks that no exception is thrown if dragGestureRecognized28* takes a while to complete.29*/3031import java.awt.AWTException;32import java.awt.Color;33import java.awt.Container;34import java.awt.Dimension;35import java.awt.Graphics;36import java.awt.Graphics2D;37import java.awt.GridLayout;38import java.awt.Point;39import java.awt.Robot;40import java.awt.datatransfer.DataFlavor;41import java.awt.datatransfer.Transferable;42import java.awt.datatransfer.UnsupportedFlavorException;43import java.awt.dnd.DnDConstants;44import java.awt.dnd.DragGestureEvent;45import java.awt.dnd.DragGestureListener;46import java.awt.dnd.DragSource;47import java.awt.dnd.DragSourceDragEvent;48import java.awt.dnd.DragSourceDropEvent;49import java.awt.dnd.DragSourceEvent;50import java.awt.dnd.DragSourceListener;51import java.awt.dnd.DropTarget;52import java.awt.dnd.DropTargetDragEvent;53import java.awt.dnd.DropTargetDropEvent;54import java.awt.dnd.DropTargetEvent;55import java.awt.dnd.DropTargetListener;56import java.awt.event.InputEvent;57import java.io.IOException;58import java.lang.reflect.InvocationTargetException;59import java.util.concurrent.CountDownLatch;60import java.util.concurrent.TimeUnit;6162import javax.swing.JFrame;63import javax.swing.JPanel;64import javax.swing.SwingUtilities;65import javax.swing.WindowConstants;6667/**68* If dragGestureRecognized() takes a while to complete and if user performs a drag quickly,69* an exception is thrown from DropTargetListener.dragEnter when it calls70* DropTargetDragEvent.getTransferable().71* <p>72* This class introduces a delay in dragGestureRecognized() to cause the exception.73*/74public class bug8024061 {75private static final DataFlavor DropObjectFlavor;76private static final int DELAY = 1000;7778static final DnDPanel panel1 = new DnDPanel(Color.yellow);79static final DnDPanel panel2 = new DnDPanel(Color.pink);80private final JFrame frame;81static Point here;82static Point there;83static Dimension d;84858687private static final CountDownLatch lock = new CountDownLatch(1);88private static volatile Exception dragEnterException = null;8990static {91DataFlavor flavor = null;92try {93flavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType);94} catch (ClassNotFoundException e) {95e.printStackTrace();96}97DropObjectFlavor = flavor;98}99100bug8024061() {101frame = new JFrame("DnDWithRobot");102frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);103104d = new Dimension(100, 100);105106panel1.setPreferredSize(d);107panel2.setPreferredSize(d);108109Container content = frame.getContentPane();110content.setLayout(new GridLayout(1, 2, 5, 5));111content.add(panel1);112content.add(panel2);113114frame.pack();115frame.setLocationRelativeTo(null);116DropObject drop = new DropObject();117drop.place(panel1, new Point(10, 10));118frame.setVisible(true);119}120121public static void main(String[] args) throws AWTException, InvocationTargetException, InterruptedException {122final bug8024061[] dnd = {null};123SwingUtilities.invokeAndWait(new Runnable() {124@Override125public void run() {126dnd[0] = new bug8024061();127}128});129final Robot robot = new Robot();130robot.setAutoDelay(10);131robot.waitForIdle();132robot.delay(200);133134JFrame frame = dnd[0].frame;135SwingUtilities.invokeAndWait(() -> {136here = panel1.getLocationOnScreen();137there = panel2.getLocationOnScreen();138});139here.translate(d.width / 2, d.height / 2);140there.translate(d.width / 2, d.height / 2);141robot.mouseMove(here.x, here.y);142robot.mousePress(InputEvent.BUTTON1_MASK);143while (here.x < there.x) {144here.x += 20;145robot.mouseMove(here.x, here.y);146System.out.println("x = " + here.x);147}148robot.mouseRelease(InputEvent.BUTTON1_MASK);149robot.waitForIdle();150robot.mousePress(InputEvent.BUTTON1_MASK);151robot.mouseRelease(InputEvent.BUTTON1_MASK);152System.out.println("finished");153154try {155if (lock.await(5, TimeUnit.SECONDS)) {156if (dragEnterException == null) {157System.out.println("Test passed.");158} else {159System.out.println("Test failed.");160dragEnterException.printStackTrace();161throw new RuntimeException(dragEnterException);162}163} else {164System.out.println("Test failed. Timeout reached");165throw new RuntimeException("Timed out waiting for dragEnter()");166}167} finally {168SwingUtilities.invokeAndWait(frame::dispose);169}170}171172class DropObject implements Transferable {173DnDPanel panel;174Color color = Color.CYAN;175int width = 50;176int height = 50;177int x;178int y;179180void draw(Graphics2D g) {181Color savedColor = g.getColor();182g.setColor(color);183g.fillRect(x, y, width, height);184g.setColor(Color.lightGray);185g.drawRect(x, y, width, height);186g.setColor(savedColor);187}188189boolean contains(int x, int y) {190return (x > this.x && x < this.x + width)191&& (y > this.y && y < this.y + height);192}193194@Override195public DataFlavor[] getTransferDataFlavors() {196return new DataFlavor[]{DropObjectFlavor};197}198199void place(DnDPanel panel, Point location) {200if (panel != this.panel) {201x = location.x;202y = location.y;203if (this.panel != null) {204this.panel.setDropObject(null);205this.panel.repaint();206}207this.panel = panel;208this.panel.setDropObject(this);209this.panel.repaint();210}211}212213@Override214public boolean isDataFlavorSupported(DataFlavor flavor) {215return DropObjectFlavor.equals(flavor);216}217218@Override219public Object getTransferData(DataFlavor flavor)220throws UnsupportedFlavorException, IOException {221if (isDataFlavorSupported(flavor)) {222return this;223} else {224throw new UnsupportedFlavorException(flavor);225}226}227}228229static class DnDPanel extends JPanel {230DropObject dropObject;231final DragSource dragSource;232final DropTarget dropTarget;233final Color color;234final DragGestureListener dgListener;235final DragSourceListener dsListener;236final DropTargetListener dtListener;237238DnDPanel(Color color) {239this.color = color;240this.dragSource = DragSource.getDefaultDragSource();241dgListener = new DragGestureListener() {242@Override243public void dragGestureRecognized(DragGestureEvent dge) {244Point location = dge.getDragOrigin();245if (dropObject != null && dropObject.contains(location.x, location.y)) {246dragSource.startDrag(dge, DragSource.DefaultCopyNoDrop, dropObject, dsListener);247try {248Thread.sleep(DELAY);249} catch (InterruptedException e) {250}251}252}253};254255dsListener = new DragSourceListener() {256@Override257public void dragEnter(DragSourceDragEvent dsde) {258}259260@Override261public void dragOver(DragSourceDragEvent dsde) {262}263264@Override265public void dropActionChanged(DragSourceDragEvent dsde) {266}267268@Override269public void dragExit(DragSourceEvent dse) {270}271272@Override273public void dragDropEnd(DragSourceDropEvent dsde) {274}275};276277dtListener = new DropTargetListener() {278@Override279public void dragEnter(DropTargetDragEvent dtde) {280if (dropObject != null) {281dtde.rejectDrag();282return;283}284dtde.acceptDrag(DnDConstants.ACTION_MOVE);285try {286Transferable t = dtde.getTransferable();287Object data = t.getTransferData(DropObjectFlavor);288} catch (Exception e) {289dragEnterException = e;290e.printStackTrace();291} finally {292lock.countDown();293}294}295296@Override297public void dragOver(DropTargetDragEvent dtde) {298if (dropObject != null) {299dtde.rejectDrag();300return;301}302dtde.acceptDrag(DnDConstants.ACTION_MOVE);303}304305@Override306public void dropActionChanged(DropTargetDragEvent dtde) {307}308309@Override310public void dragExit(DropTargetEvent dte) {311}312313@Override314public void drop(DropTargetDropEvent dtde) {315if (dropObject != null) {316dtde.rejectDrop();317return;318}319try {320dtde.acceptDrop(DnDConstants.ACTION_MOVE);321Transferable t = dtde.getTransferable();322DropObject dropObject = (DropObject) t.getTransferData(DropObjectFlavor);323Point location = dtde.getLocation();324dropObject.place(DnDPanel.this, location);325dtde.dropComplete(true);326} catch (Exception e) {327e.printStackTrace();328}329330}331};332333dragSource.createDefaultDragGestureRecognizer(this,334DnDConstants.ACTION_MOVE, dgListener);335336dropTarget = new DropTarget(this, DnDConstants.ACTION_MOVE, dtListener, true);337338}339340public void paintComponent(Graphics g) {341super.paintComponent(g);342Color savedColor = g.getColor();343g.setColor(color);344g.fillRect(0, 0, getWidth(), getHeight());345g.setColor(savedColor);346if (dropObject != null) {347dropObject.draw((Graphics2D) g);348}349}350351void setDropObject(DropObject dropObject) {352this.dropObject = dropObject;353}354355DropObject findDropObject(int x, int y) {356if (dropObject != null && dropObject.contains(x, y)) {357return dropObject;358}359return null;360}361}362}363364365