001package jmri.jmrit.display.palette;
002
003import java.awt.Color;
004import java.awt.datatransfer.DataFlavor;
005import java.awt.datatransfer.Transferable;
006import java.awt.datatransfer.UnsupportedFlavorException;
007import java.awt.dnd.DnDConstants;
008import java.awt.dnd.DropTarget;
009import java.awt.dnd.DropTargetDragEvent;
010import java.awt.dnd.DropTargetDropEvent;
011import java.awt.dnd.DropTargetEvent;
012import java.awt.dnd.DropTargetListener;
013import java.io.IOException;
014import java.util.HashMap;
015import javax.swing.Icon;
016import javax.swing.JLabel;
017
018import jmri.jmrit.catalog.ImageIndexEditor;
019import jmri.jmrit.catalog.NamedIcon;
020import org.slf4j.Logger;
021import org.slf4j.LoggerFactory;
022
023/**
024 * @author Pete Cressman Copyright (c) 2011
025 */
026public class DropJLabel extends JLabel implements DropTargetListener {
027
028    private DataFlavor _dataFlavor;
029    private HashMap<String, NamedIcon> _iconMap;
030
031    DropJLabel(Icon icon) {
032        super(icon);
033        try {
034            _dataFlavor = new DataFlavor(ImageIndexEditor.IconDataFlavorMime);
035        } catch (ClassNotFoundException cnfe) {
036            log.error("Unable to find class supporting {}", ImageIndexEditor.IconDataFlavorMime, cnfe);
037        }
038        new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
039        //if (log.isDebugEnabled()) log.debug("DropJLabel ctor");
040    }
041
042    DropJLabel(Icon icon, HashMap<String, NamedIcon> iconMap) {
043        this(icon);
044        _iconMap = iconMap;
045    }
046
047    @Override
048    public void dragExit(DropTargetEvent dte) {
049        //if (log.isDebugEnabled()) log.debug("DropJLabel.dragExit ");
050    }
051
052    @Override
053    public void dragEnter(DropTargetDragEvent dtde) {
054        //if (log.isDebugEnabled()) log.debug("DropJLabel.dragEnter ");
055    }
056
057    @Override
058    public void dragOver(DropTargetDragEvent dtde) {
059        //if (log.isDebugEnabled()) log.debug("DropJLabel.dragOver ");
060    }
061
062    @Override
063    public void dropActionChanged(DropTargetDragEvent dtde) {
064        //if (log.isDebugEnabled()) log.debug("DropJLabel.dropActionChanged ");
065    }
066
067    @Override
068    public void drop(DropTargetDropEvent e) {
069        try {
070            Transferable tr = e.getTransferable();
071            if (e.isDataFlavorSupported(_dataFlavor)) {
072                NamedIcon newIcon = new NamedIcon((NamedIcon) tr.getTransferData(_dataFlavor));
073                accept(e, newIcon);
074            } else if (e.isDataFlavorSupported(DataFlavor.stringFlavor)) {
075                String text = (String) tr.getTransferData(DataFlavor.stringFlavor);
076                if (log.isDebugEnabled()) {
077                    log.debug("drop for stringFlavor {}", text);
078                }
079                NamedIcon newIcon = new NamedIcon(text, text);
080                accept(e, newIcon);
081            } else {
082                if (log.isDebugEnabled()) {
083                    log.debug("DropJLabel.drop REJECTED!");
084                }
085                e.rejectDrop();
086            }
087        } catch (IOException ioe) {
088            if (log.isDebugEnabled()) {
089                log.debug("DropPanel.drop REJECTED!");
090            }
091            e.rejectDrop();
092        } catch (UnsupportedFlavorException ufe) {
093            if (log.isDebugEnabled()) {
094                log.debug("DropJLabel.drop REJECTED!");
095            }
096            e.rejectDrop();
097        }
098    }
099
100    protected void accept(DropTargetDropEvent e, NamedIcon newIcon) {
101        e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
102        DropTarget target = (DropTarget) e.getSource();
103        DropJLabel label = (DropJLabel) target.getComponent();
104        if (log.isDebugEnabled()) {
105            log.debug("accept drop of {} for {} name, {}", label.getClass().getName(), label.getName(),newIcon.getURL());
106        }
107        if (newIcon.getIconWidth() < 1 || newIcon.getIconHeight() < 1) {
108            label.setText(Bundle.getMessage("invisibleIcon"));
109            label.setForeground(Color.lightGray);
110        } else {
111            label.setText(null);
112        }
113        label.setIcon(newIcon);
114        if (_iconMap != null) {
115            String name = label.getName();
116            if (name != null) {
117                _iconMap.put(name, newIcon);
118            } else {
119                log.error("Map key= {}, icon= {} ", label.getName(), newIcon.getName());
120                e.dropComplete(false);
121                return;
122            }
123        }
124        e.dropComplete(true);
125        if (log.isDebugEnabled()) {
126            log.debug("DropJLabel.drop COMPLETED for {}, {}",
127                    label.getName(), newIcon.getURL());
128        }
129    }
130
131    private final static Logger log = LoggerFactory.getLogger(DropJLabel.class);
132
133}