Mega Code Archive

 
Categories / Java / Swing JFC
 

TransferHandler subclass wraps another TransferHandler and delegates most of its operations to the wrapped handler

/*  * 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);   } }