| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.log4j.chainsaw.dnd; |
| |
| |
| import org.apache.log4j.Logger; |
| import java.awt.datatransfer.DataFlavor; |
| import java.awt.Color; |
| import java.awt.datatransfer.Transferable; |
| 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.beans.PropertyChangeListener; |
| import java.beans.PropertyChangeSupport; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.swing.BorderFactory; |
| import javax.swing.JComponent; |
| |
| /** |
| * This class provides all the functionality to work out when files are dragged onto |
| * a particular JComponent instance, and then notifies listeners via |
| * the standard PropertyChangesListener semantics to indicate that a list of |
| * files have been dropped onto the target. |
| * |
| * If you wish to know whan the files have been dropped, subscribe to the "fileList" property change. |
| * |
| * @author psmith |
| * |
| */ |
| public class FileDnDTarget implements DropTargetListener{ |
| /** |
| * Logger for this class |
| */ |
| private static final Logger LOG = Logger.getLogger(FileDnDTarget.class); |
| |
| protected int acceptableActions = DnDConstants.ACTION_COPY; |
| |
| private List fileList; |
| |
| private JComponent guiTarget; |
| private Map<JComponent, DropTarget> dropTargets = new HashMap<>(); |
| |
| |
| private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); |
| /** |
| * |
| */ |
| public FileDnDTarget(JComponent c) { |
| this.guiTarget = c; |
| } |
| |
| public void addDropTargetToComponent(JComponent c){ |
| dropTargets.put(c, new DropTarget(c, this)); |
| } |
| |
| /** |
| * @param listener |
| */ |
| public void addPropertyChangeListener(PropertyChangeListener listener) { |
| propertySupport.addPropertyChangeListener(listener); |
| } |
| /** |
| * @param propertyName |
| * @param listener |
| */ |
| public void addPropertyChangeListener(String propertyName, |
| PropertyChangeListener listener) { |
| propertySupport.addPropertyChangeListener(propertyName, listener); |
| } |
| |
| /** |
| * |
| */ |
| private void decorateComponent() { |
| // TODO work out a better way of decorating a component |
| guiTarget.setBorder(BorderFactory.createLineBorder(Color.black)); |
| } |
| |
| |
| public void dragEnter(DropTargetDragEvent e) { |
| //LOG.debug(dtde); |
| if (isDragOk(e) == false) { |
| e.rejectDrag(); |
| return; |
| } |
| decorateComponent(); |
| |
| e.acceptDrag(acceptableActions); |
| } |
| |
| |
| public void dragExit(DropTargetEvent dte) { |
| removeComponentDecoration(); |
| } |
| |
| |
| public void dragOver(DropTargetDragEvent e) { |
| //LOG.debug(dtde); |
| |
| if (isDragOk(e) == false) { |
| e.rejectDrag(); |
| return; |
| } |
| e.acceptDrag(acceptableActions); |
| } |
| |
| public void drop(DropTargetDropEvent dtde) { |
| Transferable transferable = dtde.getTransferable(); |
| LOG.debug(transferable); |
| dtde.acceptDrop(acceptableActions); |
| try { |
| List list = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor); |
| LOG.debug(list); |
| setFileList(list); |
| dtde.getDropTargetContext().dropComplete(true); |
| removeComponentDecoration(); |
| |
| } catch (Exception e) { |
| LOG.error("Error with DnD", e); |
| } |
| |
| } |
| |
| public void dropActionChanged(DropTargetDragEvent dtde) { |
| //LOG.debug(dtde); |
| } |
| /** |
| * @return Returns the fileList. |
| */ |
| public final List getFileList() { |
| return fileList; |
| } |
| |
| private boolean isDragOk(DropTargetDragEvent e) { |
| DataFlavor[] flavors = new DataFlavor[] { DataFlavor.javaFileListFlavor }; |
| DataFlavor chosen = null; |
| for (DataFlavor flavor : flavors) { |
| if (e.isDataFlavorSupported(flavor)) { |
| chosen = flavor; |
| break; |
| } |
| } |
| /* |
| * the src does not support any of the StringTransferable flavors |
| */ |
| if (chosen == null) { |
| return false; |
| } |
| // the actions specified when the source |
| // created the DragGestureRecognizer |
| int sa = e.getSourceActions(); |
| |
| // we're saying that these actions are necessary |
| return (sa & acceptableActions) != 0; |
| } |
| |
| /** |
| * |
| */ |
| private void removeComponentDecoration() { |
| this.guiTarget.setBorder(null); |
| } |
| /** |
| * @param listener |
| */ |
| public void removePropertyChangeListener(PropertyChangeListener listener) { |
| propertySupport.removePropertyChangeListener(listener); |
| } |
| /** |
| * @param propertyName |
| * @param listener |
| */ |
| public void removePropertyChangeListener(String propertyName, |
| PropertyChangeListener listener) { |
| propertySupport.removePropertyChangeListener(propertyName, listener); |
| } |
| |
| /** |
| * @param fileList The fileList to set. |
| */ |
| private final void setFileList(List fileList) { |
| Object oldValue = this.fileList; |
| this.fileList = fileList; |
| propertySupport.firePropertyChange("fileList", oldValue, this.fileList); |
| } |
| } |