Перетаскивание узла из JTree и переход на JLabel для выполнения действия

#java #swing #drag-and-drop #applet #jtree

#java #swing #перетаскивание #апплет #jtree

Вопрос:

Я хочу реализовать DnD в своей системе, перетащив узел из JTree и поместив его в JLabel.

JLabel — это значок с определенными свойствами о машине, и, перетаскивая информацию из узла JTree на JLabel, я хочу, чтобы он мог отправлять сообщение клиенту, прослушивающему эту машину.

Любая помощь очень ценится!

Пример метода label:

 private void makeLabel(String html, final String version) {
    // Create a button to link to the DR environment
    //JButton button = new JButton(html);
    JLabel machineLabel = new JLabel();
    machineLabel.setTransferHandler(new TransferHandler("text"));
    MouseListener listener = new DragMouseAdapter();
    machineLabel.addMouseListener(listener);
    machineLabel.setIcon(onlineIcon);
    machineLabel.setToolTipText("IP: "   html);
    //Add the button to the panel and make sure it appears
    machineLabel.setSize(25, 10);
    vecIcons.addElement(machineLabel);
    buttonPanel.add(machineLabel);
    buttonPanel.setVisible(true);
    buttonPanel.validate();
    dynaScrollPane.validate();
    buttonPanel.repaint();
    dynaScrollPane.repaint();
  }
  

Метод DragMouseAdapter:

     private class DragMouseAdapter extends MouseAdapter {
public void mousePressed(MouseEvent e) {
  JComponent c = (JComponent) e.getSource();
  TransferHandler handler = c.getTransferHandler();
  handler.exportAsDrag(c, e, TransferHandler.LINK);
  }
}
  

Затем, чтобы сделать мое дерево перетаскиваемым, я просто:

 exampleTree.setDragEnabled(true);
  

Комментарии:

1. Может быть, это может вам помочь: перетаскивание и передача данных и этот пример .

2. Я полагаю, что это покрывается обычной поддержкой Java DnD .

3. Я попробовал код, приведенный в руководстве по Java, но на самом деле он не работал с JLabels, вместо того, чтобы переходить на метку, он помещал управляющую строку рядом с меткой.

4. Это больше похоже на проблему с рендерингом Swing, чем на проблему с DnD. Не могли бы вы опубликовать scce ?

5. Я только что опубликовал все связанные методы и код в своем исходном сообщении.

Ответ №1:

не уверен, что я понимаю вашу настройку: предполагая, что вы хотите, чтобы метка была целью удаления, просто реализуйте пользовательский Transferhandler, который принимает dataflavour, экспортируемый деревом, и что-то с ним

Редактировать

Чтобы получить доступ к TreePath, также используйте пользовательский Transferhandler для дерева: переопределите его createTransferable, который возвращает TreePath:

     final DataFlavor flavor =new DataFlavor(TreePath.class, "treePath");
    TransferHandler treeHandler = new TransferHandler() {
        DataFlavor[] pathFlavour = new DataFlavor[] 
                  {flavor};

        /** 
         * @inherited <p>
         */
        @Override
        protected Transferable createTransferable(JComponent c) {
            JTree tree = (JTree) c;
            final TreePath path = tree.getSelectionPath();
            Transferable transferable = new Transferable() {

                @Override
                public DataFlavor[] getTransferDataFlavors() {
                    return pathFlavour;
                }

                @Override
                public boolean isDataFlavorSupported(DataFlavor flavor) {
                    return pathFlavour[0].equals(flavor);
                }

                @Override
                public Object getTransferData(DataFlavor flavor)
                        throws UnsupportedFlavorException, IOException {
                    return path;
                }

            };
            return transferable;
        }

        public int getSourceActions(JComponent c) {
            return COPY;
        }

    };
    tree.setTransferHandler(treeHandler);
    JLabel labelTarget = new JLabel("I'm a drop target!");
    TransferHandler labelHandler = new TransferHandler() {

        /** 
         * @inherited <p>
         */
        @Override
        public boolean importData(JComponent comp, Transferable t) {
            try {
                LOG.info("import from: "    t.getTransferData(flavor));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;
        }

        /** 
         * @inherited <p>
         */
        @Override
        public boolean canImport(JComponent comp,
                DataFlavor[] transferFlavors) {
            return true;
        }

    };
    labelTarget.setTransferHandler(labelHandler);
  

нет необходимости в дополнительном MouseListener

Комментарии:

1. Верно; насколько я помню, все соответствующие события мыши обрабатываются java.awt.dnd.

2. Это работает хорошо, хотя мне нужно иметь возможность узнать точное местоположение, из которого произошло удаление. Так, например, если у меня есть дерево с корневым узлом «Server1», затем другой узел под названием «Example», в котором есть значение «Example Val», как я могу заставить его отображать что-то вроде «Перетаскивание пришло с Server1-> Example-> ExampleVal»? Я не могу найти способ сделать это с помощью DataFlavours.