View Javadoc

1   package org.apache.log4j.chainsaw.dnd;
2   
3   
4   import org.apache.log4j.Logger;
5   import java.awt.datatransfer.DataFlavor;
6   import java.awt.Color;
7   import java.awt.datatransfer.Transferable;
8   import java.awt.dnd.DnDConstants;
9   import java.awt.dnd.DropTarget;
10  import java.awt.dnd.DropTargetDragEvent;
11  import java.awt.dnd.DropTargetDropEvent;
12  import java.awt.dnd.DropTargetEvent;
13  import java.awt.dnd.DropTargetListener;
14  import java.beans.PropertyChangeListener;
15  import java.beans.PropertyChangeSupport;
16  import java.util.HashMap;
17  import java.util.List;
18  import java.util.Map;
19  
20  import javax.swing.BorderFactory;
21  import javax.swing.JComponent;
22  
23  /***
24   * This class provides all the functionality to work out when files are dragged onto
25   * a particular JComponent instance, and then notifies listeners via
26   * the standard PropertyChangesListener semantics to indicate that a list of 
27   * files have been dropped onto the target.
28   * 
29   * If you wish to know whan the files have been dropped, subscribe to the "fileList" property change.
30   * 
31   * @author psmith
32   *
33   */
34  public class FileDnDTarget implements DropTargetListener{
35      /***
36       * Logger for this class
37       */
38      private static final Logger LOG = Logger.getLogger(FileDnDTarget.class);
39  
40      protected int acceptableActions = DnDConstants.ACTION_COPY;
41  
42      private DropTarget dropTarget;
43      private List fileList;
44  
45      private JComponent guiTarget;
46      private Map dropTargets = new HashMap();
47      
48      
49      private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
50      /***
51       * 
52       */
53      public FileDnDTarget(JComponent c) {
54          this.guiTarget = c;
55          dropTarget = new DropTarget(this.guiTarget, this);
56      }
57      
58      public void addDropTargetToComponent(JComponent c){
59          dropTargets.put(c, new DropTarget(c, this));
60      }
61      
62      /***
63       * @param listener
64       */
65      public void addPropertyChangeListener(PropertyChangeListener listener) {
66          propertySupport.addPropertyChangeListener(listener);
67      }
68      /***
69       * @param propertyName
70       * @param listener
71       */
72      public void addPropertyChangeListener(String propertyName,
73              PropertyChangeListener listener) {
74          propertySupport.addPropertyChangeListener(propertyName, listener);
75      }
76  
77      /***
78       * 
79       */
80      private void decorateComponent() {
81  //        TODO work out a better way of decorating a component
82          guiTarget.setBorder(BorderFactory.createLineBorder(Color.black));
83      }
84  
85  
86      public void dragEnter(DropTargetDragEvent e) {
87          //LOG.debug(dtde);
88          if (isDragOk(e) == false) {
89              e.rejectDrag();
90              return;
91          }
92          decorateComponent();
93  
94          e.acceptDrag(acceptableActions);
95      }
96  
97  
98      public void dragExit(DropTargetEvent dte) {
99          removeComponentDecoration();
100     }
101 
102 
103     public void dragOver(DropTargetDragEvent e) {
104         //LOG.debug(dtde);
105 
106         if (isDragOk(e) == false) {
107             e.rejectDrag();
108             return;
109         }
110         e.acceptDrag(acceptableActions);
111     }
112 
113     public void drop(DropTargetDropEvent dtde) {
114         Transferable transferable = dtde.getTransferable();
115         LOG.debug(transferable);
116         dtde.acceptDrop(acceptableActions);
117         try {
118             List list = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor);
119             LOG.debug(list);
120             setFileList(list);
121             dtde.getDropTargetContext().dropComplete(true);
122             removeComponentDecoration();
123 
124         } catch (Exception e) {
125             LOG.error("Error with DnD", e);
126         }
127         
128     }
129 
130     public void dropActionChanged(DropTargetDragEvent dtde) {
131         //LOG.debug(dtde);
132     }
133     /***
134      * @return Returns the fileList.
135      */
136     public final List getFileList() {
137         return fileList;
138     }
139 
140     private boolean isDragOk(DropTargetDragEvent e) {
141     	DataFlavor[] flavors = new DataFlavor[] { DataFlavor.javaFileListFlavor };
142     	DataFlavor chosen = null;
143     	for (int i = 0; i < flavors.length; i++) {
144     		if (e.isDataFlavorSupported(flavors[i])) {
145     			chosen = flavors[i];
146     			break;
147     		}
148     	}
149     	/*
150     	 * the src does not support any of the StringTransferable flavors
151     	 */
152     	if (chosen == null) {
153     		return false;
154     	}
155     	// the actions specified when the source
156     	// created the DragGestureRecognizer
157     	int sa = e.getSourceActions();
158     
159     	// we're saying that these actions are necessary
160     	if ((sa & acceptableActions) == 0)
161     		return false;
162     	return true;
163     }
164 
165     /***
166      * 
167      */
168     private void removeComponentDecoration() {
169         this.guiTarget.setBorder(null);
170     }
171     /***
172      * @param listener
173      */
174     public void removePropertyChangeListener(PropertyChangeListener listener) {
175         propertySupport.removePropertyChangeListener(listener);
176     }
177     /***
178      * @param propertyName
179      * @param listener
180      */
181     public void removePropertyChangeListener(String propertyName,
182             PropertyChangeListener listener) {
183         propertySupport.removePropertyChangeListener(propertyName, listener);
184     }
185     
186     /***
187      * @param fileList The fileList to set.
188      */
189     private  final void setFileList(List fileList) {
190         Object oldValue = this.fileList;
191         this.fileList = fileList;
192         propertySupport.firePropertyChange("fileList", oldValue, this.fileList);
193     }
194 }