Java tutorial
/* * Copyright (c) 2004 David Flanagan. All rights reserved. * This code is from the book Java Examples in a Nutshell, 3nd Edition. * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied. * You may study, use, and modify it for any non-commercial purpose, * including teaching and use in open-source projects. * You may distribute it non-commercially as long as you retain this notice. * For a commercial use license, or to purchase the book, * please visit http://www.davidflanagan.com/javaexamples3. */ import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.InputEvent; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.List; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.TransferHandler; /** * This TransferHandler subclass wraps another TransferHandler and delegates * most of its operations to the wrapped handler. It adds the ability to to drop * or paste files using the predefined DataFlavor.javaFileListFlavor. When a * file list is pasted or dropped, it assumes the files are text, reads them in * order, concatenates their contents, and then passes the resulting string to * the wrapped handler for insertion. */ public class FileTransferHandler extends TransferHandler { TransferHandler wrappedHandler; // The handler that we wrap // We use this array to test the wrapped handler static DataFlavor[] stringFlavorArray = new DataFlavor[] { DataFlavor.stringFlavor }; /** Pass an existing TransferHandler to this constructor */ public FileTransferHandler(TransferHandler wrappedHandler) { if (wrappedHandler == null) // Fail immediately on null throw new NullPointerException(); this.wrappedHandler = wrappedHandler; // Remember wrapped handler } /** * This method returns true if the TransferHandler knows how to work with one * of the specified flavors. This implementation first checks the superclass, * then checks for fileListFlavor support */ public boolean canImport(JComponent c, DataFlavor[] flavors) { // If the wrapped handler can import it, we're done if (wrappedHandler.canImport(c, flavors)) return true; // Otherwise, if the wrapped handler can handle string imports, then // see if we are being offered a list of files that we can convert // to a string. if (wrappedHandler.canImport(c, stringFlavorArray)) { for (int i = 0; i < flavors.length; i++) if (flavors[i].equals(DataFlavor.javaFileListFlavor)) return true; } // Otherwise, we can't import any of the flavors. return false; } /** * If the wrapped handler can import strings and the specified Transferable * can provide its data as a List of File objects, then we read the files, and * pass their contents as a string to the wrapped handler. Otherwise, we offer * the Transferable to the wrapped handler to handle on its own. */ public boolean importData(JComponent c, Transferable t) { // See if we're offered a java.util.List of java.io.File objects. // We handle this case first because the Transferable is likely to // also offer the filenames as strings, and we want to import the // file contents, not their names! if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor) && wrappedHandler.canImport(c, stringFlavorArray)) { try { List filelist = (List) t.getTransferData(DataFlavor.javaFileListFlavor); // Loop through the files to determine total size int numfiles = filelist.size(); int numbytes = 0; for (int i = 0; i < numfiles; i++) { File f = (File) filelist.get(i); numbytes += (int) f.length(); } // There will never be more characters than bytes in the files char[] text = new char[numbytes]; // to hold file contents int p = 0; // current position in the text[] array // Loop through the files again, reading their content as text for (int i = 0; i < numfiles; i++) { File f = (File) filelist.get(i); Reader r = new BufferedReader(new FileReader(f)); p += r.read(text, p, (int) f.length()); } // Convert the character array to a string and wrap it // in a pre-defined Transferable class for transferring strings StringSelection selection = new StringSelection(new String(text, 0, p)); // Ask the wrapped handler to import the string return wrappedHandler.importData(c, selection); } // If anything goes wrong, just beep to tell the user catch (UnsupportedFlavorException e) { c.getToolkit().beep(); // audible error return false; // return failure code } catch (IOException e) { c.getToolkit().beep(); // audible error return false; // return failure code } } // Otherwise let the wrapped class handle this transferable itself return wrappedHandler.importData(c, t); } /* * The following methods just delegate to the wrapped TransferHandler */ public void exportAsDrag(JComponent c, InputEvent e, int action) { wrappedHandler.exportAsDrag(c, e, action); } public void exportToClipboard(JComponent c, Clipboard clip, int action) { wrappedHandler.exportToClipboard(c, clip, action); } public int getSourceActions(JComponent c) { return wrappedHandler.getSourceActions(c); } public Icon getVisualRepresentation(Transferable t) { // This method is not currently (Java 1.4) used by Swing return wrappedHandler.getVisualRepresentation(t); } /** * This class demonstrates the FileTransferHandler by installing it on a * JTextArea component and providing a JFileChooser to drag and cut files. */ public static void main(String[] args) { // Here's the text area. Note how we wrap our TransferHandler // around the default handler returned by getTransferHandler() JTextArea textarea = new JTextArea(); TransferHandler defaultHandler = textarea.getTransferHandler(); textarea.setTransferHandler(new FileTransferHandler(defaultHandler)); // Here's a JFileChooser, with dragging explicitly enabled. JFileChooser filechooser = new JFileChooser(); filechooser.setDragEnabled(true); // Display them both in a window JFrame f = new JFrame("File Transfer Handler Test"); f.getContentPane().add(new JScrollPane(textarea), "Center"); f.getContentPane().add(filechooser, "South"); f.setSize(400, 600); f.setVisible(true); } }