View Javadoc

1   /*
2    *  XNap Commons
3    *
4    *  Copyright (C) 2005  Felix Berger
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or (at your option) any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package org.xnap.commons.gui.dnd;
21  
22  import java.awt.datatransfer.DataFlavor;
23  import java.awt.datatransfer.Transferable;
24  import java.awt.datatransfer.UnsupportedFlavorException;
25  import java.io.File;
26  import java.io.IOException;
27  import java.net.MalformedURLException;
28  import java.net.URL;
29  import java.net.URLDecoder;
30  import java.util.ArrayList;
31  import java.util.List;
32  import java.util.StringTokenizer;
33  import javax.swing.JComponent;
34  import javax.swing.TransferHandler;
35  
36  /***
37   * Abstract handler class easing drag and drop support of file objects.
38   * <p>
39   * Also handles Linux Desktop file drag and drops which don't seem to translate
40   * to the {@link java.awt.datatransfer.DataFlavor#javaFileListFlavor}.
41   * <p>
42   * Subclasses should override {@link #createTransferable(JComponent)}
43   * and {@link #importFiles(JComponent, List)}.
44   * 
45   * @author Felix Berger
46   */
47  public abstract class AbstractFileTransferHandler extends TransferHandler 
48  {
49  
50  	/***
51  	 * URI flavor used for file drag and drops on the Linux desktop.
52  	 */
53  	public static DataFlavor linuxURIFlavor;
54  
55  	static {
56  		linuxURIFlavor = createLinuxURIFlavor();
57  	}
58  	
59  	private static DataFlavor createLinuxURIFlavor() 
60  	{
61  		try { 
62  			  return new DataFlavor("text/uri-list;class=java.lang.String"); 
63  		}
64  		catch (ClassNotFoundException cnfe) { 
65  			return null;
66  		}
67  	}
68  	
69  	/***
70  	 * Returns true if one of the supported flavors is either 
71  	 * {@link DataFlavor#javaFileListFlavor} or {@link #linuxURIFlavor}.
72  	 */
73  	@Override
74  	public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) 
75  	{
76  		for (DataFlavor flavor : transferFlavors) {
77  			if (flavor.equals(DataFlavor.javaFileListFlavor) 
78  					|| flavor.equals(AbstractFileTransferHandler.linuxURIFlavor)) {
79  				return true;
80  			}
81  		}
82  		return false;
83  	}
84  	
85  	/***
86  	 * Returns {@link TransferHandler#COPY}.
87  	 */
88  	@Override
89  	public int getSourceActions(JComponent c) 
90  	{
91  		return TransferHandler.COPY;
92  	}
93  
94  	/***
95  	 * Returns <code>null</code>.
96  	 * <p>
97  	 * Subclasses can return a {@link FileTransferable}.
98  	 */
99  	@Override
100 	protected Transferable createTransferable(JComponent c)
101 	{
102 		return null;
103 	}
104 
105 	/***
106 	 * Returns <code>false</code>, thus disallowing dropping of files on
107 	 * the component <code>comp</code>.
108 	 * <p>
109 	 * Subclasses should import the list of <code>files</code> and return true
110 	 * on success.
111 	 */
112 	public boolean importFiles(JComponent comp, List<File> files)
113 	{
114 		return false;
115 	}
116 	
117 	/***
118 	 * Overriden to extract the file lists from the different types of 
119 	 * transferables.
120 	 */
121 	@Override
122 	public boolean importData(JComponent comp, Transferable t) 
123 	{
124 		List<File> files = null;
125 		try {
126 			if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
127 				files = (List<File>)t.getTransferData(DataFlavor.javaFileListFlavor);
128 			}
129 			else if (t.isDataFlavorSupported(AbstractFileTransferHandler.linuxURIFlavor)) {
130 				String s = (String)t.getTransferData(AbstractFileTransferHandler.linuxURIFlavor);
131 				StringTokenizer st = new StringTokenizer(s, System.getProperty("line.separator")); 
132 				files = new ArrayList<File>(); 
133 				while (st.hasMoreTokens()) { 
134 					String file = st.nextToken(); 
135 					try { 
136 						URL url = new URL(file); 
137 						files.add(new File(URLDecoder.decode(url.getPath()))); 
138 					} 
139 					catch (MalformedURLException mue) { 
140 					} 
141 				}
142 			}
143 		}
144 		catch (UnsupportedFlavorException e) {
145 			return false;
146 		}
147 		catch (IOException e) {
148 			return false;
149 		}
150 		return (files != null && !files.isEmpty()) ? importFiles(comp, files) : false;
151 	}
152 
153 }