001package jmri.jmrit.catalog;
002
003import java.awt.datatransfer.DataFlavor;
004import java.awt.datatransfer.Transferable;
005import java.awt.datatransfer.UnsupportedFlavorException;
006import java.awt.dnd.DnDConstants;
007import java.awt.dnd.DragGestureEvent;
008import java.awt.dnd.DragGestureListener;
009import java.awt.dnd.DragSource;
010import java.awt.dnd.DragSourceDragEvent;
011import java.awt.dnd.DragSourceDropEvent;
012import java.awt.dnd.DragSourceEvent;
013import java.awt.dnd.DragSourceListener;
014import java.io.IOException;
015import javax.swing.JLabel;
016import org.slf4j.Logger;
017import org.slf4j.LoggerFactory;
018
019/**
020 * Gives a JLabel the capability to Drag and Drop.
021 *
022 * @author Pete Cressman Copyright 2009, 2016
023 */
024public class DragJLabel extends JLabel implements DragGestureListener, DragSourceListener, Transferable {
025
026    protected DataFlavor _dataFlavor;
027
028    public DragJLabel(DataFlavor flavor) {
029        super();
030        init(flavor);
031    }
032    
033    public DragJLabel(DataFlavor flavor, NamedIcon icon) {
034        super(icon);
035        init(flavor);
036    }
037    
038    public DragJLabel(DataFlavor flavor, String text) {
039        super(text);
040        init(flavor);
041    }
042    
043    private void init(DataFlavor flavor) {
044        DragSource dragSource = DragSource.getDefaultDragSource();
045        dragSource.createDefaultDragGestureRecognizer(this,
046                DnDConstants.ACTION_COPY, this);
047        _dataFlavor = flavor;        
048    }
049
050    /**
051     * Source can override to prohibit dragging if data is incomplete
052     * when dragGestureRecognized() is called.
053     *
054     * @return Source's choice to allow drag
055     */
056    protected boolean okToDrag() {
057        return true;
058    }
059
060    /**
061     * ************** DragGestureListener **************
062     */
063    @Override
064    public void dragGestureRecognized(DragGestureEvent e) {
065        log.debug("DragJLabel.dragGestureRecognized ");
066        if (okToDrag()) {
067            e.startDrag(DragSource.DefaultCopyDrop, this, this);            
068        }
069    }
070
071    /**
072     * ************** DragSourceListener ***********
073     */
074    @Override
075    public void dragDropEnd(DragSourceDropEvent e) {
076        log.debug("DragJLabel.dragDropEnd ");
077    }
078
079    @Override
080    public void dragEnter(DragSourceDragEvent e) {
081        // log.debug("DragJLabel.DragSourceDragEvent ");
082    }
083
084    @Override
085    public void dragExit(DragSourceEvent e) {
086        // log.debug("DragJLabel.dragExit ");
087    }
088
089    @Override
090    public void dragOver(DragSourceDragEvent e) {
091        // log.debug("DragJLabel.dragOver ");
092    }
093
094    @Override
095    public void dropActionChanged(DragSourceDragEvent e) {
096        // log.debug("DragJLabel.dropActionChanged ");
097    }
098
099    /**
100     * ************* Transferable ********************
101     */
102    @Override
103    public DataFlavor[] getTransferDataFlavors() {
104        // log.debug("DragJLabel.getTransferDataFlavors ");
105        return new DataFlavor[]{_dataFlavor, DataFlavor.stringFlavor};
106    }
107
108    @Override
109    public boolean isDataFlavorSupported(DataFlavor flavor) {
110        // log.debug("DragJLabel.isDataFlavorSupported ");
111        if (DataFlavor.stringFlavor.equals(flavor)) {
112            return true;
113        }
114        return _dataFlavor.equals(flavor);
115    }
116
117    @Override
118    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
119        log.debug("DragJLabel.getTransferData ");
120        if (_dataFlavor.equals(flavor)) {
121            return getIcon();
122        }
123        if (DataFlavor.stringFlavor.equals(flavor)) {
124            NamedIcon icon = (NamedIcon) getIcon();
125            return icon.getURL();
126        }
127        return null;
128    }
129
130    private final static Logger log = LoggerFactory.getLogger(DragJLabel.class);
131
132}