从JTable拖放到JLayeredPane [英] Drag and Drop from JTable to JLayeredPane
问题描述
如何在 JTable 和 JLayeredPane 之间创建拖放.
How to create Drag and drop between JTable and JLayeredPane.
有没有人知道如何实现这一目标?
Does anyone have any ideas how to implement this?
我需要通过拖放在JTable和JLayeredPane之间传输对象.
推荐答案
您必须至少做几件事才能使它起作用:
You have to do a few things at minimum to get this to work:
- Call
setDragEnabled(true)
on yourJTable
instance - Set the
JTable
s andJLayeredPane
sDropTarget
- Create a draggable
Component
to add to theJLayeredPane
要设置Component
s DropTarget
,请调用setDropTarget(DropTarget d)
方法并传递一个匿名内部类作为参数.删除 Transferable
s到Component
的数据应该位于drop(DropTargetDropEvent dtde)
方法中.
To set a Component
s DropTarget
, call the setDropTarget(DropTarget d)
method and pass an anonymous inner class as the argument. Code that drops the Transferable
s data into the Component
should be located in the drop(DropTargetDropEvent dtde)
method.
下面的代码片段显示了如何接收Transferable
并将其插入到发起放置的JTable
行中:
The below snippet shows how to receive a Transferable
and insert it into the row of a JTable
where the drop was initiated:
table.setDropTarget(new DropTarget() {
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
try {
// get row to put new item in
int row = table.rowAtPoint(dtde.getLocation());
// inserting row:
((DefaultTableModel) table.getModel()).insertRow(
//if the row wasn't found, add it to the end of the JTable
row == -1 ? table.getRowCount() : row,
// pass string flavor of transferable data as row data parameter
new Object[] {dtde.getTransferable()
.getTransferData(DataFlavor.stringFlavor)});
} catch(UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
});
下面的代码片段再次接收到Transferable
,但是将其添加到JLayeredPane
的末尾.请注意,因为我为JLayeredPane
分配了BoxLayout(SwingConstants.VERTICAL)
,所以组件被添加到了JLayeredPane
的末尾.
This below snippet again receives a Transferable
but instead adds it to the end of a JLayeredPane
. Note that components are added to the end of the JLayeredPane
because I assign a BoxLayout(SwingConstants.VERTICAL)
to it.
layeredPane.setDropTarget(new DropTarget() {
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
try {
// create draggable label to add to layered pane
// creating this class will be explained next
final DraggableLabel label = new DraggableLabel(
(String) dtde.getTransferable()
.getTransferData(DataFlavor.stringFlavor));
// add label to layered pane
layeredPane.add(label, JLayeredPane.DEFAULT_LAYER);
layeredPane.revalidate();
layeredPane.repaint();
} catch(UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
});
要创建可拖动的Component
(在本示例中为JLabel
),您必须:
To create a draggable Component
(In this example a JLabel
), you must:
- 创建一个新的类,该类
extends
JLabel
和implements
DragGestureListener
和DragSourceListener
- 覆盖所有必需的方法
- 在构造函数中:
- 创建一个新的
DragSource
- 创建
DragGestureRecognizer
并将其分配给this
JLabel
子类和this
DragGestureListener
- Create a new class that
extends
JLabel
andimplements
DragGestureListener
andDragSourceListener
- Override all the necessary methods
- In the constructor:
- Create a new
DragSource
- Create a
DragGestureRecognizer
and assign it tothis
theJLabel
subclass andthis
theDragGestureListener
class DraggableLabel extends JLabel implements DragGestureListener, DragSourceListener { private DragSource dragSource; DraggableLabel(String text) { super(text); // create the drag source dragSource = new DragSource(); // assign this component a DragGestureRecognizer dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_COPY_OR_MOVE, this); // for contrast with other items in layered pane setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY)); } @Override public void dragGestureRecognized(DragGestureEvent evt) { dragSource.startDrag( evt, //trigger event DragSource.DefaultMoveDrop, // icon new StringSelection(getText()), // transferable data this); // this the DragSourceListener } @Override public void dragEnter(DragSourceDragEvent evt) {} @Override public void dragOver(DragSourceDragEvent evt) {} @Override public void dragExit(DragSourceEvent evt) {} @Override public void dropActionChanged(DragSourceDragEvent evt) {} @Override public void dragDropEnd(DragSourceDropEvent evt) {} }
完整的示例:
Full working example:
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDropEvent; import java.io.IOException; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JTable; import javax.swing.WindowConstants; import javax.swing.table.DefaultTableModel; class DragDropExample { public static void main(String[] args) { EventQueue.invokeLater(() -> { final JFrame frame = new JFrame("JLabel Text Example"); final JTable table = new JTable(new DefaultTableModel( new Object[][] { {"Item 1"}, {"Item 2"}, {"Item 3"}, {"Item 4"}, {"Item 5"}}, new String[] {"Column Name"})); table.setDragEnabled(true); table.setDropTarget(new DropTarget() { @Override public synchronized void drop(DropTargetDropEvent dtde) { try { // get row to put new item in int row = table.rowAtPoint(dtde.getLocation()); // inserting row: ((DefaultTableModel) table.getModel()).insertRow( //if the row wasn't found, add it to the end of the JTable row == -1 ? table.getRowCount() : row, // pass string flavor of transferable data as row data parameter new Object[] {dtde.getTransferable() .getTransferData(DataFlavor.stringFlavor)}); } catch(UnsupportedFlavorException | IOException e) { e.printStackTrace(); } } }); final JLayeredPane layeredPane = new JLayeredPane() { @Override public Dimension getPreferredSize() { return new Dimension(200, 300); } }; layeredPane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); layeredPane.setLayout(new BoxLayout(layeredPane, BoxLayout.Y_AXIS)); layeredPane.setDropTarget(new DropTarget() { @Override public synchronized void drop(DropTargetDropEvent dtde) { try { // create draggable label to add to layered pane // creating this class will be explained next final DraggableLabel label = new DraggableLabel( (String) dtde.getTransferable() .getTransferData(DataFlavor.stringFlavor)); // add label to layered pane layeredPane.add(label, JLayeredPane.DEFAULT_LAYER); layeredPane.revalidate(); layeredPane.repaint(); } catch(UnsupportedFlavorException | IOException e) { e.printStackTrace(); } } }); frame.getContentPane().add(table, BorderLayout.WEST); frame.getContentPane().add(layeredPane); frame.pack(); frame.setLocationByPlatform(true); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); }); } static class DraggableLabel extends JLabel implements DragGestureListener, DragSourceListener { private DragSource dragSource; DraggableLabel(String text) { super(text); // create the drag source dragSource = new DragSource(); // assign this component a DragGestureRecognizer dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_COPY_OR_MOVE, this); // for contrast with other items setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY)); } @Override public void dragGestureRecognized(DragGestureEvent evt) { dragSource.startDrag( evt, //trigger event DragSource.DefaultMoveDrop, new StringSelection(getText()), this); } @Override public void dragEnter(DragSourceDragEvent evt) {} @Override public void dragOver(DragSourceDragEvent evt) {} @Override public void dragExit(DragSourceEvent evt) {} @Override public void dropActionChanged(DragSourceDragEvent evt) {} @Override public void dragDropEnd(DragSourceDropEvent evt) {} } }
这篇关于从JTable拖放到JLayeredPane的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- Create a new
- 创建一个新的