如何将 JLabel 拖放到 JPanel 中

在研究了如何使用Label DnD 后,我遇到了使用此解决方案的问题:


 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();

    }

}

当用户单击并按住 JLabel 时,X 和 Y 会随着鼠标移动而被记录下来。但是,我不知道如何知道单击何时停止(即,用户到达他的目标 JPanel)然后将文本移入其中。


允许 JPanels 接收放置操作的唯一参考是执行以下操作:


new JPanel().setDropTarget(getDropTarget());

但是,我无法再次找到有关通过 JLabel 作为坐标(绝对布局)放置目标的任何参考。


动漫人物
浏览 413回答 1
1回答

慕斯王

在查看@ 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()方法来覆盖一个方法,因此每次将标签移动到不同的容器时,它都会执行单独的操作。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java