package org.openjump.core.ui.plugin.file; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TooManyListenersException; import javax.swing.BorderFactory; import javax.swing.JRootPane; import javax.swing.border.Border; import org.openjump.core.ui.plugin.AbstractUiPlugIn; import com.vividsolutions.jump.workbench.JUMPWorkbench; import com.vividsolutions.jump.workbench.plugin.PlugInContext; import com.vividsolutions.jump.workbench.ui.ErrorHandler; import com.vividsolutions.jump.workbench.ui.GUIUtil; import com.vividsolutions.jump.workbench.ui.WorkbenchFrame; public class FileDragDropPlugin extends AbstractUiPlugIn implements DropTargetListener { public static final Set<String> PROJECT_EXTENSIONS = new HashSet<String>( Arrays.asList(new String[] { "jmp", "jcs" })); private static final String ZERO_CHAR_STRING = "" + (char)0; private WorkbenchFrame frame; private Border border = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(0f, 0f, 1f, 0.25f)); private Border savedBorder; /** * Initialise plug-in. * * @param context The plug-in context. * @exception Exception If there was an error initialising the plug-in. */ public void initialize(final PlugInContext context) throws Exception { super.initialize(context); JUMPWorkbench workbench = workbenchContext.getWorkbench(); frame = workbench.getFrame(); makeDropTarget(frame, true); } public void dragEnter(DropTargetDragEvent event) { if (isDragOk(event)) { JRootPane rootPane = frame.getRootPane(); savedBorder = rootPane.getBorder(); rootPane.setBorder(border); event.acceptDrag(DnDConstants.ACTION_COPY); } else { event.rejectDrag(); } } public void dragExit(DropTargetEvent event) { JRootPane rootPane = frame.getRootPane(); rootPane.setBorder(savedBorder); } public void dragOver(DropTargetDragEvent event) { } public void drop(DropTargetDropEvent event) { try { Transferable tr = event.getTransferable(); List<File> files = null; if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { event.acceptDrop(DnDConstants.ACTION_COPY); files = (List)tr.getTransferData(DataFlavor.javaFileListFlavor); } else { DataFlavor[] flavors = tr.getTransferDataFlavors(); boolean handled = false; for (DataFlavor flavor : flavors) { if (flavor.isRepresentationClassReader()) { event.acceptDrop(DnDConstants.ACTION_COPY); BufferedReader reader = new BufferedReader( flavor.getReaderForText(tr)); handled = true; files = new ArrayList<File>(); String fileName = null; while ((fileName = reader.readLine()) != null) { try { // kde seems to append a 0 char to the end of the reader if (!ZERO_CHAR_STRING.equals(fileName)) { File file = new File(new URI(fileName)); files.add(file); } } catch (java.net.URISyntaxException e) { ErrorHandler errorHandler = workbenchContext.getErrorHandler(); errorHandler.handleThrowable(e); } } } } if (!handled) { event.rejectDrop(); return; } } if (files != null) { List<File> projectFiles = new ArrayList<File>(); List<File> dataFiles = new ArrayList<File>(); for (File file : files) { String extension = GUIUtil.getExtension(file); if (PROJECT_EXTENSIONS.contains(extension)) { projectFiles.add(file); } else { dataFiles.add(file); } } if (!dataFiles.isEmpty()) { OpenFilePlugIn filePlugin = new OpenFilePlugIn(workbenchContext, dataFiles.toArray(new File[0])); filePlugin.actionPerformed(new ActionEvent(this, 0, "")); } if (!projectFiles.isEmpty()) { OpenProjectPlugIn projectPlugin = new OpenProjectPlugIn( workbenchContext, projectFiles.toArray(new File[0])); projectPlugin.actionPerformed(new ActionEvent(this, 0, "")); } } event.getDropTargetContext().dropComplete(true); } catch (UnsupportedFlavorException e) { ErrorHandler errorHandler = workbenchContext.getErrorHandler(); errorHandler.handleThrowable(e); } catch (IOException e) { ErrorHandler errorHandler = workbenchContext.getErrorHandler(); errorHandler.handleThrowable(e); } finally { JRootPane rootPane = frame.getRootPane(); rootPane.setBorder(savedBorder); } } public void dropActionChanged(DropTargetDragEvent event) { if (isDragOk(event)) { event.acceptDrag(DnDConstants.ACTION_COPY); } else { event.rejectDrag(); } } private boolean isDragOk(final DropTargetDragEvent event) { DataFlavor[] flavors = event.getCurrentDataFlavors(); for (DataFlavor flavor : flavors) { if (flavor.equals(DataFlavor.javaFileListFlavor) || flavor.isRepresentationClassReader()) { return true; } } return false; } private void makeDropTarget(final Component component, boolean recursive) { final DropTarget target = new DropTarget(); try { target.addDropTargetListener(this); } catch (TooManyListenersException e) { ErrorHandler errorHandler = workbenchContext.getErrorHandler(); errorHandler.handleThrowable(e); } component.addHierarchyListener(new java.awt.event.HierarchyListener() { public void hierarchyChanged(java.awt.event.HierarchyEvent evt) { java.awt.Component parent = component.getParent(); if (parent == null) { component.setDropTarget(null); } else { new DropTarget(component, FileDragDropPlugin.this); } } }); if (component.getParent() != null) { new DropTarget(component, this); } if (recursive && (component instanceof Container)) { Container cont = (Container)component; Component[] comps = cont.getComponents(); for (Component child : comps) { makeDropTarget(child, recursive); } } } }