001package jmri.jmrix.can.cbus.swing;
002
003import java.awt.datatransfer.StringSelection;
004import java.awt.datatransfer.Transferable;
005import java.awt.dnd.DragSource;
006import java.awt.dnd.DragSourceMotionListener;
007import java.awt.dnd.DragSourceDragEvent;
008import java.util.TimerTask;
009import javax.swing.JComponent;
010import javax.swing.JFrame;
011import javax.swing.JLabel;
012import javax.swing.JTable;
013import javax.swing.TransferHandler;
014import jmri.jmrix.can.CanSystemConnectionMemo;
015import jmri.jmrix.can.cbus.CbusEvent;
016import jmri.jmrix.can.cbus.CbusNameService;
017import jmri.jmrix.can.cbus.eventtable.CbusEventTableDataModel;
018import jmri.jmrix.can.cbus.node.CbusNodeEventTableDataModel;
019import jmri.util.TimerUtil;
020
021// import org.slf4j.Logger;
022// import org.slf4j.LoggerFactory;
023
024/**
025 * Drag and drop handler for CBUS Events being dragged from a table.
026 * @author Steve Young Copyright (C) 2019
027 */
028public class CbusTableRowEventDnDHandler extends TransferHandler implements DragSourceMotionListener {
029
030    private int nn,en;
031    private JLabel tempLabel;
032    private JFrame frame;
033    private final CbusNameService nameService;
034    private TimerTask showFrameTimerTask;
035    private DragSource source;
036    
037    public CbusTableRowEventDnDHandler(CanSystemConnectionMemo memo, JTable table){
038        super();
039        nameService = new CbusNameService(memo);
040        initFrame();
041
042    }
043    
044    final void initFrame(){
045        tempLabel = new JLabel();
046        frame = new JFrame();
047        frame.setUndecorated(true);
048        frame.add(tempLabel);
049        frame.setFocusableWindowState(false);
050        
051        source = DragSource.getDefaultDragSource();
052        source.addDragSourceMotionListener(this);
053    
054    }
055    
056    /**
057     * {@inheritDoc}
058     */
059    @Override
060    public void dragMouseMoved(DragSourceDragEvent e){
061        mouseMoved(e.getX(),e.getY());
062    }
063        
064    protected void mouseMoved(int x, int y){
065        clearFrameTimeout();
066        if (nn<0 || en<0){
067            return;
068        }
069        tempLabel.setText(nameService.getEventNodeString(nn, en));
070        frame.repaint();
071        frame.pack();
072
073        frame.setLocation(x+20, y+15);
074        frame.setVisible(true);
075        frame.toFront();
076        
077        setFrameTimeout();
078    
079    }
080    
081    private void clearFrameTimeout(){
082        if (showFrameTimerTask != null ) {
083            showFrameTimerTask.cancel();
084            showFrameTimerTask = null;
085            frame.setVisible(false);
086        }
087    }
088    
089    private void setFrameTimeout(){
090        showFrameTimerTask = new TimerTask() {
091            @Override
092            public void run() {
093                showFrameTimerTask = null;
094                frame.setVisible(false);
095            }
096        };
097        TimerUtil.schedule(showFrameTimerTask, ( 650 ) );
098    }
099    
100    /**
101     * {@inheritDoc}
102     */
103    @Override
104    public int getSourceActions(JComponent c) {
105        return COPY;
106    }
107
108    /**
109     * {@inheritDoc}
110     */
111    @Override
112    public Transferable createTransferable(JComponent c) {
113        nn = -1;
114        en = -1;
115        if (!(c instanceof JTable )){
116            return null;
117        }
118        
119        setNnEn((JTable) c);
120        if (nn<0 || en<0){
121            return null;
122        }
123        
124        return new StringSelection( CbusEvent.getJmriString(nn, en) );
125    }
126    
127    private void setNnEn(JTable table){
128    
129        int row = table.getSelectedRow();
130        if (row < 0) {
131            return;
132        }
133        
134        if ( table.getName().equals(CbusEventTableDataModel.class.getName())
135            || table.getName().equals(CbusNodeEventTableDataModel.class.getName())) {
136            
137            nn = (Integer) table.getModel().getValueAt(table.convertRowIndexToModel(row), CbusNodeEventTableDataModel.NODE_NUMBER_COLUMN); // node number
138            en = (Integer) table.getModel().getValueAt(table.convertRowIndexToModel(row), CbusNodeEventTableDataModel.EVENT_NUMBER_COLUMN); // event number
139        }
140    }
141    
142    public void dispose(){
143        source.removeDragSourceMotionListener(this);
144        clearFrameTimeout();
145        frame.dispose();
146    }
147    
148    // private final static Logger log = LoggerFactory.getLogger(CbusTableRowEventDnDHandler.class);
149
150}