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