/*========================================================================= Program: FusionViewer Module: $RCSfile: FileAndTextTransferHandler.java,v $ Language: Java Date: $Date: 2007/02/02 19:27:57 $ Version: $Revision: 1.2 $ Copyright (c) Insightful Corporation. All rights reserved. See Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ package org.fusionviewer.ui; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.TransferHandler; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.text.Position; /**\class FileAndTextTransferHandler *\brief TransferHandler for drag and drop of file paths into a JTextField. * * Based on the drag and drop example program in the Java Tutorial. * http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html * * Usage: * FileAndTextTransferHandler transferHandler = new FileAndTextTransferHandler(); * JTextField field = new JTextField(); * field.setDragEnabled(true); * field.setTransferHandler(transferHandler); */ public class FileAndTextTransferHandler extends TransferHandler { private JTextField source; private boolean shouldRemove; // Start and end position in the source text. // We need this information when performing a MOVE // in order to remove the dragged text from the source. Position p0 = null, p1 = null; public FileAndTextTransferHandler() { } public boolean importData(JComponent c, Transferable t) { JTextField tc; if (!canImport(c, t.getTransferDataFlavors())) { return false; } try { tc = (JTextField) c; if (hasFileFlavor(t.getTransferDataFlavors())) { List files = (List) t.getTransferData(DataFlavor.javaFileListFlavor); Iterator fileIterator = files.iterator(); if (fileIterator.hasNext()) { File file = (File) fileIterator.next(); tc.setText(file.getAbsolutePath()); } } else if (hasStringFlavor(t.getTransferDataFlavors())) { if (tc.equals(source) && (tc.getCaretPosition() >= p0.getOffset()) && (tc.getCaretPosition() <= p1.getOffset())) { shouldRemove = false; return true; } String str = (String) t.getTransferData(DataFlavor.stringFlavor); tc.replaceSelection(str); return true; } } catch (UnsupportedFlavorException ufe) { JOptionPane.showMessageDialog(c, "Error transferring data\n\n" + ufe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } catch (IOException ieo) { JOptionPane.showMessageDialog(c, "Error transferring data\n\n" + ieo.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } return false; } protected Transferable createTransferable(JComponent c) { source = (JTextField) c; int start = source.getSelectionStart(); int end = source.getSelectionEnd(); Document doc = source.getDocument(); if (start == end) return null; try { p0 = doc.createPosition(start); p1 = doc.createPosition(end); } catch (BadLocationException e) { JOptionPane.showMessageDialog(c, "Error transferring data\n\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } shouldRemove = true; return new StringSelection(source.getSelectedText()); } public int getSourceActions(JComponent c) { return COPY_OR_MOVE; } // Remove the old text if the action is a MOVE. // However, we do not allow dropping on top of the selected text, // so in that case do nothing. protected void exportDone(JComponent c, Transferable data, int action) { if (shouldRemove && (action == MOVE)) { if ((p0 != null) && (p1 != null) && (p0.getOffset() != p1.getOffset())) { try { JTextComponent tc = (JTextComponent) c; tc.getDocument().remove(p0.getOffset(), p1.getOffset() - p0.getOffset()); } catch (BadLocationException e) { JOptionPane.showMessageDialog(c, "Error transferring data\n\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } } source = null; } public boolean canImport(JComponent c, DataFlavor[] flavors) { if (hasFileFlavor(flavors)) return true; if (hasStringFlavor(flavors)) return true; return false; } private boolean hasFileFlavor(DataFlavor[] flavors) { for (int i = 0; i < flavors.length; i++) { if (DataFlavor.javaFileListFlavor.equals(flavors[i])) return true; } return false; } private boolean hasStringFlavor(DataFlavor[] flavors) { for (int i = 0; i < flavors.length; i++) { if (DataFlavor.stringFlavor.equals(flavors[i])) return true; } return false; } }