Java 如何将JLabel拖放到JPanel中
在研究了如何使用后,我发现使用此解决方案:Java 如何将JLabel拖放到JPanel中,java,swing,drag-and-drop,Java,Swing,Drag And Drop,在研究了如何使用后,我发现使用此解决方案: public class LayerItem extends JLabel { int x = 0, y = 0; public LayerItem(String text) { this.setText(text); this.addMouseMotionListener(new MouseAdapter(){ @Override public voi
public class LayerItem extends JLabel {
int x = 0, y = 0;
public LayerItem(String text) {
this.setText(text);
this.addMouseMotionListener(new MouseAdapter(){
@Override
public void mouseDragged(MouseEvent evt){
lblMouseDragged(evt);
}
});
}
protected void lblMouseDragged(MouseEvent evt){
this.x = evt.getX();
this.y = evt.getY();
}
}
当用户单击并按住时,会在鼠标移动时记录X和Y的标记。然而,我被困在如何知道点击何时停止(即,用户到达他的目标JPanel),然后将文本移动到其中
允许JPanels接收drop操作的唯一参考是执行以下操作:
new JPanel().setDropTarget(getDropTarget());
但是,我再也找不到任何关于使用Coords(绝对布局)通过JLabel作为放置目标的参考。在查看了@I发布的几个示例后,我提出了一个扩展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,然后再拖回来):
为了将来使用,我将创建一个
onTransfer()
方法,并创建我自己的LayerContainerHandler()
,它覆盖了run()
方法,因此每次标签移动到不同的容器时,它执行不同的操作。在查看了@I发布的几个示例后,提出了一个扩展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,然后再拖回来):
为了将来使用,我将创建一个
onTransfer()
方法,并创建我自己的LayerContainerHandler()
方法,它覆盖了run()
方法,因此每次将标签移动到不同的容器时,它都会执行不同的操作。基本上,您的示例不起作用,它没有做您认为的事情。相反,也许可以看看或者——基本上任何东西都可以利用可转移的,因为这不是经常被问到的,因为你应该经常查阅源代码Drag'n'Drop是非常复杂的,但是它遵循一些基本规则,如果你能理解这些规则,使它成为一个非常灵活和强大的API。基本上,你的例子不会起作用,它没有做你认为它是什么。相反,也许可以看看或者——基本上任何东西都可以利用可转移的,因为这不是经常被问到的,因为你应该经常查阅源代码Drag'n'Drop是非常复杂的,但它遵循一些基本规则,如果你能了解这些规则,它将成为一个非常灵活和强大的API