001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.client.util.dnd;
019:
020: import java.awt.Color;
021: import java.awt.LayoutManager;
022: import java.awt.datatransfer.DataFlavor;
023: import java.awt.datatransfer.Transferable;
024: import java.awt.datatransfer.UnsupportedFlavorException;
025: import java.awt.dnd.DnDConstants;
026: import java.awt.dnd.DragGestureEvent;
027: import java.awt.dnd.DragGestureListener;
028: import java.awt.dnd.DragSource;
029: import java.awt.dnd.DropTarget;
030: import java.awt.dnd.DropTargetDragEvent;
031: import java.awt.dnd.DropTargetDropEvent;
032: import java.awt.dnd.DropTargetEvent;
033: import java.awt.dnd.DropTargetListener;
034: import java.io.IOException;
035: import java.io.Serializable;
036: import java.util.List;
037: import java.util.Vector;
038: import java.util.logging.Level;
039: import java.util.logging.Logger;
040:
041: import javax.swing.JComponent;
042: import javax.swing.JPanel;
043: import javax.swing.TransferHandler;
044:
045: import de.finix.contelligent.client.base.ContelligentComponent;
046:
047: public class JPanelDND extends JPanel implements DragGestureListener {
048:
049: private static Logger logger = Logger.getLogger(JPanelDND.class
050: .getName());
051:
052: private ContelligentComponent component;
053:
054: private Color defaultBackground, highlightBackground;
055:
056: private int sourceActions = DnDConstants.ACTION_COPY
057: | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK;
058:
059: private List<ComponentDropListener> componentDropListeners = new Vector<ComponentDropListener>();
060:
061: private String environment;
062:
063: public JPanelDND(LayoutManager layout, String environment) {
064: super (layout);
065: this .environment = environment;
066: // init drag and drop...
067: setTransferHandler(new PanelTransferHandler());
068: setDropEnabled(true);
069: defaultBackground = getBackground();
070: highlightBackground = defaultBackground.brighter();
071: }
072:
073: public void setComponent(ContelligentComponent component) {
074: this .component = component;
075: }
076:
077: public ContelligentComponent getComponent() {
078: return component;
079: }
080:
081: public void setSourceActions(int sourceActions) {
082: this .sourceActions = sourceActions;
083: }
084:
085: public void setDropEnabled(boolean dropEnabled) {
086: if (dropEnabled) {
087: setDropTarget(new DropTarget(this , new DropHandler()));
088: } else {
089: setDropTarget(null);
090: }
091: }
092:
093: public void setDragEnabled(boolean dragEnabled) {
094: if (dragEnabled) {
095: DragSource dragSource = new DragSource();
096: dragSource.createDefaultDragGestureRecognizer(this ,
097: sourceActions, this );
098: }
099: }
100:
101: private class PanelTransferHandler extends TransferHandler {
102: public boolean canImport(JComponent component,
103: DataFlavor[] transferFlavors) {
104: // this label can only import contelligent components...
105: for (int i = 0; i < transferFlavors.length; i++) {
106: if (transferFlavors[i] == SingleComponentTransferable.componentFlavor) {
107: return true;
108: }
109: }
110: return false;
111: }
112:
113: protected Transferable createTransferable(JComponent c) {
114: return new SingleComponentTransferable(component,
115: environment);
116: }
117:
118: public int getSourceActions(JComponent component) {
119: return sourceActions;
120: }
121: }
122:
123: private class DropHandler implements DropTargetListener,
124: Serializable {
125:
126: private boolean canImport = true;
127:
128: private boolean actionSupported(int action) {
129: return true;
130: }
131:
132: // --- DropTargetListener methods -----------------------------------
133:
134: public void dragEnter(DropTargetDragEvent e) {
135: DataFlavor[] flavors = e.getCurrentDataFlavors();
136:
137: JComponent c = (JComponent) e.getDropTargetContext()
138: .getComponent();
139: TransferHandler importer = c.getTransferHandler();
140:
141: if (importer != null && importer.canImport(c, flavors)) {
142: canImport = true;
143: } else {
144: canImport = false;
145: }
146:
147: int dropAction = e.getDropAction();
148:
149: if (canImport && actionSupported(dropAction)) {
150: e.acceptDrag(dropAction);
151: setBackground(highlightBackground);
152: } else {
153: e.rejectDrag();
154: }
155: }
156:
157: public void dragOver(DropTargetDragEvent e) {
158: int dropAction = e.getDropAction();
159:
160: if (canImport && actionSupported(dropAction)) {
161: e.acceptDrag(dropAction);
162: } else {
163: e.rejectDrag();
164: }
165: }
166:
167: public void dragExit(DropTargetEvent e) {
168: setBackground(defaultBackground);
169: }
170:
171: public void drop(DropTargetDropEvent e) {
172: final int dropAction = e.getDropAction();
173:
174: JComponent c = (JComponent) e.getDropTargetContext()
175: .getComponent();
176: TransferHandler importer = c.getTransferHandler();
177:
178: setBackground(defaultBackground);
179:
180: if (canImport && importer != null
181: && actionSupported(dropAction)) {
182: try {
183: e.acceptDrop(dropAction);
184: Transferable transferable = e.getTransferable();
185: final ContelligentComponent draggedComponent = (ContelligentComponent) transferable
186: .getTransferData(SingleComponentTransferable.componentFlavor);
187: e.dropComplete(true);
188: // notify all listenrs that a drop has occured
189: fireComponentDropEvent(new ComponentDropEvent(
190: draggedComponent, component, dropAction,
191: environment));
192: } catch (UnsupportedFlavorException ufe) {
193: e.dropComplete(false);
194: logger
195: .log(
196: Level.WARNING,
197: "Unsupported transferable was dropped on a panel",
198: ufe);
199: } catch (IOException ioe) {
200: e.dropComplete(false);
201: logger.log(Level.WARNING,
202: "Transferable could not be imported", ioe);
203: }
204: } else {
205: e.rejectDrop();
206: }
207: }
208:
209: public void dropActionChanged(DropTargetDragEvent e) {
210: int dropAction = e.getDropAction();
211:
212: if (canImport && actionSupported(dropAction)) {
213: e.acceptDrag(dropAction);
214: } else {
215: e.rejectDrag();
216: }
217: }
218: }
219:
220: public void dragGestureRecognized(DragGestureEvent event) {
221: JComponent c = (JComponent) event.getComponent();
222: TransferHandler th = c.getTransferHandler();
223: th.exportAsDrag(c, event.getTriggerEvent(),
224: TransferHandler.COPY);
225: }
226:
227: private void fireComponentDropEvent(ComponentDropEvent e) {
228: for (int i = 0; i < componentDropListeners.size(); i++) {
229: ((ComponentDropListener) componentDropListeners.get(i))
230: .componentDropped(e);
231: }
232: }
233:
234: public void addComponentDropListener(ComponentDropListener listener) {
235: componentDropListeners.add(listener);
236: }
237:
238: public void removeComponentDropListener(
239: ComponentDropListener listener) {
240: componentDropListeners.remove(listener);
241: }
242: }
|