如何在 JTable 和 JLayeredPane 之间创建拖放。
有谁有任何想法如何实现这一目标?
我需要通过在JTable和JLayeredPane 之间拖放来转移对象。
最佳答案
您至少要做一些事情才能使它起作用:
setDragEnabled(true)
实例JTable
JTable
和JLayeredPane
DropTarget
Component
以添加到JLayeredPane
要设置
Component
的DropTarget
,请调用setDropTarget(DropTarget d)
方法并传递一个匿名内部类作为参数。将 Transferable
的数据放入Component
的代码应位于drop(DropTargetDropEvent dtde)
方法中。以下代码段显示了如何接收
Transferable
并将其插入到开始放置的JTable
的行中: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)
的末尾。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
),您必须:extends
JLabel
和implements
DragGestureListener
和 DragSourceListener
DragSource
DragGestureRecognizer
并将其分配给this
JLabel
子类和this
DragGestureListener
DragSource
方法dragGestureRecognized(DragGestureEvent evt)
开始拖动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) {}
}
完整的工作示例:
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) {}
}
}
关于java - 从JTable拖放到JLayeredPane,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40906950/