001package jmri.jmrit.display.palette;
002
003import java.awt.Color;
004import java.awt.Dimension;
005import java.awt.datatransfer.DataFlavor;
006import java.awt.datatransfer.Transferable;
007import java.awt.dnd.DnDConstants;
008import java.awt.dnd.DragGestureEvent;
009import java.awt.dnd.DragGestureListener;
010import java.awt.dnd.DragSource;
011import java.awt.dnd.DragSourceDragEvent;
012import java.awt.dnd.DragSourceDropEvent;
013import java.awt.dnd.DragSourceEvent;
014import java.awt.dnd.DragSourceListener;
015import javax.swing.BorderFactory;
016import javax.swing.JComponent;
017import javax.swing.JPanel;
018import org.slf4j.Logger;
019import org.slf4j.LoggerFactory;
020
021/**
022 * Gives a JComponent the capability to Drag and Drop
023 * <hr>
024 * This file is part of JMRI.
025 * <p>
026 * JMRI is free software; you can redistribute it and/or modify it under the
027 * terms of version 2 of the GNU General Public License as published by the Free
028 * Software Foundation. See the "COPYING" file for a copy of this license.
029 * <p>
030 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
031 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
032 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
033 *
034 * @author Pete Cressman Copyright 2011
035 *
036 */
037public abstract class DragJComponent extends JPanel implements DragGestureListener, DragSourceListener, Transferable {
038
039    DataFlavor _dataFlavor;
040    JComponent _component;
041
042    public DragJComponent(DataFlavor flavor,  JComponent comp) {
043        super();
044        _component = comp;
045        setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black),
046                Bundle.getMessage("dragToPanel")));
047        // guestimate border is about 5 pixels thick. plus some margin
048        add(comp);
049        setPreferredSize();
050        setToolTipText(Bundle.getMessage("ToolTipDragIcon"));
051        DragSource dragSource = DragSource.getDefaultDragSource();
052        dragSource.createDefaultDragGestureRecognizer(this,
053                DnDConstants.ACTION_COPY, this);
054        _dataFlavor = flavor;
055    }
056
057    @Override
058    public void invalidate() {
059        setPreferredSize();
060        super.invalidate();
061    }
062
063    protected void setPreferredSize() {
064        Dimension dim = _component.getSize();
065        int width = Math.max(100, dim.width + 30);
066        int height = Math.max(65, dim.height + 35);
067        setPreferredSize(new java.awt.Dimension(width, height));
068    }
069
070    protected JComponent getThing() {
071        return _component;
072    }
073        
074    protected boolean okToDrag() {
075        return true;
076    }
077    
078    /**
079     * ************** DragGestureListener **************
080     */
081    @Override
082    public void dragGestureRecognized(DragGestureEvent e) {
083        if (log.isDebugEnabled()) {
084            log.debug("DragJLabel.dragGestureRecognized ");
085        }
086        if (okToDrag()) {
087            e.startDrag(DragSource.DefaultCopyDrop, this, this);            
088        }
089    }
090
091    /**
092     * ************** DragSourceListener ***********
093     */
094    @Override
095    public void dragDropEnd(DragSourceDropEvent e) {
096        if (log.isDebugEnabled()) {
097            log.debug("DragJLabel.dragDropEnd ");
098        }
099    }
100
101    @Override
102    public void dragEnter(DragSourceDragEvent e) {
103    }
104
105    @Override
106    public void dragExit(DragSourceEvent e) {
107    }
108
109    @Override
110    public void dragOver(DragSourceDragEvent e) {
111    }
112
113    @Override
114    public void dropActionChanged(DragSourceDragEvent e) {
115    }
116
117    /**
118     * ************* Transferable ********************
119     */
120    @Override
121    public DataFlavor[] getTransferDataFlavors() {
122        return new DataFlavor[]{_dataFlavor, DataFlavor.stringFlavor};
123    }
124
125    @Override
126    public boolean isDataFlavorSupported(DataFlavor flavor) {
127        return _dataFlavor.equals(flavor);
128    }
129
130    private final static Logger log = LoggerFactory.getLogger(DragJComponent.class);
131}