1 回答
TA贡献1864条经验 获得超2个赞
在查看@ MadProgrammer发布的几个示例后,我想出了一个扩展 JPanel 和 JLabel 的解决方案。这是 JLabel 类:
public class LayerItem extends JLabel {
public LayerItem(String text) {
this.setText(text);
this.setTransferHandler(new ValueExportTransferHandler(text));
this.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
JLabel lbl = (JLabel) e.getSource();
TransferHandler handle = lbl.getTransferHandler();
handle.exportAsDrag(lbl, e, TransferHandler.COPY);
}
});
}
protected static class ValueExportTransferHandler extends TransferHandler {
public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor;
private String value;
public ValueExportTransferHandler(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public int getSourceActions(JComponent c) {
return DnDConstants.ACTION_COPY_OR_MOVE;
}
@Override
protected Transferable createTransferable(JComponent c) {
Transferable t = new StringSelection(getValue());
return t;
}
@Override
protected void exportDone(JComponent source, Transferable data, int action) {
super.exportDone(source, data, action);
// Clean up and remove the LayerItem that was moved
((LayerItem) source).setVisible(false);
((LayerItem) source).getParent().remove((LayerItem) source);
}
}
}
这是 JPanel 的类:
public class LayerContainer extends JPanel {
public LayerContainer() {
this.setTransferHandler(new ValueImportTransferHandler());
this.setLayout(new GridBagLayout()); // Optional layout
this.setBorder(new CompoundBorder(new LineBorder(Color.DARK_GRAY), new EmptyBorder(20, 20, 20, 20))); // Optional border
}
protected static class ValueImportTransferHandler extends TransferHandler {
public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor;
public ValueImportTransferHandler() {
}
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
return support.isDataFlavorSupported(SUPPORTED_DATE_FLAVOR);
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
boolean accept = false;
if (canImport(support)) {
try {
Transferable t = support.getTransferable();
Object value = t.getTransferData(SUPPORTED_DATE_FLAVOR);
if (value instanceof String) { // Ensure no errors
// TODO: here you can create your own handler
// ie: ((LayerContainer) component).getHandler()....
Component component = support.getComponent();
LayerItem j = new LayerItem((String) value);
((LayerContainer) component).add(j); // Add a new drag JLabel
accept = true;
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
return accept;
}
}
}
这是一个如何使用它的示例(从一个 JPanel 拖到另一个并再次返回):
JPanel left_panel = new LayerContainer();
panel_1.setBounds(28, 47, 129, 97);
add(panel_1);
LayerContainer right_panel = new LayerContainer();
layerContainer.setBounds(203, 47, 129, 97);
add(layerContainer);
JLabel lblToDrag = new LayerItem("Drag Me");
GridBagConstraints gbc_lblToDrag = new GridBagConstraints();
gbc_lblDragMe.gridx = 0;
gbc_lblDragMe.gridy = 0;
panel_right.add(lblToDrag, gbc_lblToDrag);
为了将来使用,我将创建一个onTransfer()方法并创建我自己LayerContainerHandler()的run()方法来覆盖一个方法,因此每次将标签移动到不同的容器时,它都会执行单独的操作。
添加回答
举报