/* File: DnDSupport.java * Copyright (C) 2002-2003 The University of Iowa * Created by: Jeremy Faden * Jessica Swanner * Edward E. West * * This file is part of the das2 library. * * das2 is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.das2.util; import java.awt.*; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.*; /** * * @author eew */ public abstract class DnDSupport { private Component component; private DnDSupport parent; private int ops; private GestureRecognizer gestureRecognizer; protected DnDSupport(Component component, int ops, DnDSupport parent) { this.component = component; this.parent = parent; this.ops = ops; component.setDropTarget(new DropTarget(component, ops, new DropHandler())); } public void setParent(DnDSupport parent) { this.parent = parent; } protected abstract int canAccept(DataFlavor[] flavors, int x, int y, int action); protected abstract boolean importData(Transferable t, int x, int y, int action); protected abstract void done(); protected abstract void exportDone(Transferable t, int action); protected abstract Transferable getTransferable(int x, int y, int action); private int canAcceptInternal(DataFlavor[] flavors, int x, int y, int action) { int result = canAccept(flavors, x, y, action); if (result == -1 && parent != null) { return parent.canAcceptInternal(flavors, x + component.getX(), y + component.getY(), action); } return result; } private boolean importDataInternal(Transferable t, int x, int y, int action) { if (canAccept(t.getTransferDataFlavors(), x, y, action) != -1) { return importData(t, x, y, action); } else if (parent != null) { return parent.importDataInternal(t, x + component.getX(), y + component.getY(), action); } else { return false; } } private void doneInternal() { done(); if (parent != null) { parent.doneInternal(); } } public void startDrag(int x, int y, int action, java.awt.event.MouseEvent evt) { if (gestureRecognizer == null) { gestureRecognizer = new GestureRecognizer(component, new DragHandler()); } gestureRecognizer.startDrag(x, y, action, evt); } private class DropHandler implements DropTargetListener { public void dragEnter(DropTargetDragEvent dtde) { Point location = dtde.getLocation(); int action = canAcceptInternal(dtde.getCurrentDataFlavors(), location.x, location.y, dtde.getDropAction()); if (action == -1) { dtde.rejectDrag(); } else { dtde.acceptDrag(action); } } public void dragExit(DropTargetEvent dte) { doneInternal(); } public void dragOver(DropTargetDragEvent dtde) { Point location = dtde.getLocation(); int action = canAcceptInternal(dtde.getCurrentDataFlavors(), location.x, location.y, dtde.getDropAction()); if (action == -1) { dtde.rejectDrag(); } else { dtde.acceptDrag(action); } } public void drop(DropTargetDropEvent dtde) { Point location = dtde.getLocation(); int action = canAcceptInternal(dtde.getCurrentDataFlavors(), location.x, location.y, dtde.getDropAction()); if (action == -1) { dtde.rejectDrop(); } else { dtde.acceptDrop(action); boolean success = importDataInternal(dtde.getTransferable(), location.x, location.y, dtde.getDropAction()); dtde.dropComplete(success); } doneInternal(); } public void dropActionChanged(DropTargetDragEvent dtde) { } } private class GestureRecognizer extends java.awt.dnd.DragGestureRecognizer { GestureRecognizer(Component component, DragHandler handler) { super(DragSource.getDefaultDragSource(), component, ops, handler); } void startDrag(int x, int y, int action, java.awt.event.MouseEvent evt) { appendEvent(evt); fireDragGestureRecognized(action, new Point(x, y)); } protected void registerListeners() {} protected void unregisterListeners() {} } private class DragHandler implements DragGestureListener, DragSourceListener { public void dragGestureRecognized(DragGestureEvent dge) { Point p = dge.getDragOrigin(); int action = dge.getDragAction(); Transferable t = getTransferable(p.x, p.y, action); if (t != null) { dge.startDrag(new Cursor(Cursor.HAND_CURSOR), t, this); } } public void dragDropEnd(DragSourceDropEvent dsde) { DragSourceContext dsc = dsde.getDragSourceContext(); if (dsde.getDropSuccess()) { exportDone(dsc.getTransferable(), dsde.getDropAction()); } else { exportDone(null, DnDConstants.ACTION_NONE); } } public void dragEnter(DragSourceDragEvent dsde) { } public void dragExit(DragSourceEvent dse) { } public void dragOver(DragSourceDragEvent dsde) { } public void dropActionChanged(DragSourceDragEvent dsde) { } } }