当前位置: 首页 > 知识库问答 >
问题:

拖动树视图的节点

姬捷
2023-03-14

使用此示例,我想创建带有节点的TreeView,我可以拖动这些节点来更改它们的位置。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeItem.TreeModificationEvent;
import javafx.scene.control.TreeView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class MainApp extends Application {

    private EventHandler<TreeModificationEvent<DynamicTreeNodeModel>> branchExpandedEventHandler;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Application.launch(MainApp.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Example Dynamic Tree");
        primaryStage.setResizable(true);
        final VBox box = new VBox();
        box.setFillWidth(false);
        Scene scene = new Scene(box);
        primaryStage.setScene(scene);
        box.getChildren().add(this.getExampleTree());
        primaryStage.show();
    }

    private TreeView<DynamicTreeNodeModel> getExampleTree() {
        DynamicTreeNodeModel rootNode = new RandomDynamicTreeNodeModel(null, "Root Node");

        TreeView<DynamicTreeNodeModel> treeView = new TreeView<DynamicTreeNodeModel>();

        treeView.setCellFactory(new Callback<TreeView<DynamicTreeNodeModel>, TreeCell<DynamicTreeNodeModel>>() {
            @Override
            public TreeCell call(TreeView<DynamicTreeNodeModel> param) {
                return new DnDCell(param);
            }
        });


        treeView.setPrefSize(1000, 750);
        TreeItem rootItem = new TreeItem(rootNode);
        branchExpandedEventHandler = new EventHandler<TreeModificationEvent<DynamicTreeNodeModel>>() {
            public void handle(TreeModificationEvent<DynamicTreeNodeModel> event) {
//                System.out.println("handling event " + event);
                TreeItem<DynamicTreeNodeModel> item = event.getTreeItem();
                populateTreeItem(item);
            }
        };

        rootItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
        treeView.setShowRoot(true);
        treeView.setRoot(rootItem);
        populateTreeItem(rootItem);
        rootItem.setExpanded(true);
//        treeView.setCellFactory(new LearningTreeCellFactory());
        return treeView;
    }

    private void populateTreeItem(TreeItem<DynamicTreeNodeModel> item) {
        DynamicTreeNodeModel node = item.getValue();
        boolean isPopulated = node.isPopulated();
        boolean areGrandChildrenPopulated = node.areChildenPopulated();
        node.populateToDepth(2);
        if (!isPopulated) {
            for (DynamicTreeNodeModel childNode : node.getChildren()) {
                TreeItem childItem = new TreeItem(childNode);
                childItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
                item.getChildren().add(childItem);
            }
        }
        if (!areGrandChildrenPopulated) {
            int i = 0;
            for (TreeItem childItem : item.getChildren()) {
                // get cooresponding node in the model
                DynamicTreeNodeModel childNode = node.getChildren().get(i);
                i++;
                for (DynamicTreeNodeModel grandChildNode : childNode.getChildren()) {
                    TreeItem grandChildItem = new TreeItem(grandChildNode);
                    grandChildItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
                    childItem.getChildren().add(grandChildItem);
                }
            }
        }
    }

    private static interface DynamicTreeNodeModel {

        public String getName();

        public void setName(String name);

        public boolean isPopulated();

        public boolean areChildenPopulated();

        public List<DynamicTreeNodeModel> getChildren();

        public void setChildren(List<DynamicTreeNodeModel> children);

        public DynamicTreeNodeModel getParent();

        public void setParent(DynamicTreeNodeModel parent);

        public void populateToDepth(int depth);

        @Override
        public String toString();
    }

    private static class RandomDynamicTreeNodeModel implements DynamicTreeNodeModel {

        private DynamicTreeNodeModel parent;
        private String name;
        private List<DynamicTreeNodeModel> children = null;

        public RandomDynamicTreeNodeModel(DynamicTreeNodeModel parent, String name) {
            this.parent = parent;
            this.name = name;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public void setName(String name) {
            this.name = name;
        }

        @Override
        public boolean isPopulated() {
            if (children == null) {
                return false;
            }
            return true;
        }

        @Override
        public boolean areChildenPopulated() {
            if (!this.isPopulated()) {
                return false;
            }
            for (DynamicTreeNodeModel child : this.children) {
                if (!child.isPopulated()) {
                    return false;
                }
            }
            return true;
        }

        @Override
        public List<DynamicTreeNodeModel> getChildren() {
            return children;
        }

        @Override
        public void setChildren(List<DynamicTreeNodeModel> children) {
            this.children = children;
        }

        @Override
        public DynamicTreeNodeModel getParent() {
            return parent;
        }

        @Override
        public void setParent(DynamicTreeNodeModel parent) {
            this.parent = parent;
        }
        private static Random random = new Random();

        @Override
        public void populateToDepth(int depth) {
            if (depth <= 0) {
                return;
            }
            if (children == null) {
                int num = random.nextInt(5);
                System.out.println("got a random number " + num);
                children = new ArrayList(num);
                for (int i = 0; i < num; i++) {
                    children.add(new RandomDynamicTreeNodeModel(this, "child " + i));
                }
            }
            int childDepth = depth - 1;
            for (DynamicTreeNodeModel child : children) {
                child.populateToDepth(childDepth);
            }
        }

        @Override
        public String toString() {
            return this.name;
        }
    }


    public class DnDCell extends TreeCell<DynamicTreeNodeModel> {

        private TreeView<DynamicTreeNodeModel> parentTree;

        public DnDCell(final TreeView<DynamicTreeNodeModel> parentTree) {
            this.parentTree = parentTree;
            // ON SOURCE NODE.
            setOnDragDetected(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    System.out.println("Drag detected on " + item);
                    if (item == null) {
                        return;
                    }
                    Dragboard dragBoard = startDragAndDrop(TransferMode.MOVE);
                    ClipboardContent content = new ClipboardContent();
                    content.put(DataFormat.PLAIN_TEXT, item.toString());
                    dragBoard.setContent(content);
                    event.consume();
                }
            });
            setOnDragDone(new EventHandler<DragEvent>() {
                @Override
                public void handle(DragEvent dragEvent) {
                    System.out.println("Drag done on " + item);
                    dragEvent.consume();
                }
            });
            // ON TARGET NODE.
//            setOnDragEntered(new EventHandler<DragEvent>() {
//                @Override
//                public void handle(DragEvent dragEvent) {
//                    System.out.println("Drag entered on " + item);
//                    dragEvent.consume();
//                }
//            });
            setOnDragOver(new EventHandler<DragEvent>() {
                @Override
                public void handle(DragEvent dragEvent) {
                    System.out.println("Drag over on " + item);
                    if (dragEvent.getDragboard().hasString()) {
                        int valueToMove = Integer.parseInt(dragEvent.getDragboard().getString());
                        if (valueToMove != item) {
                            // We accept the transfer!!!!!
                            dragEvent.acceptTransferModes(TransferMode.MOVE);
                        }
                    }
                    dragEvent.consume();
                }
            });
//            setOnDragExited(new EventHandler<DragEvent>() {
//                @Override
//                public void handle(DragEvent dragEvent) {
//                    System.out.println("Drag exited on " + item);
//                    dragEvent.consume();
//                }
//            });
            setOnDragDropped(new EventHandler<DragEvent>() {
                @Override
                public void handle(DragEvent dragEvent) {
                    System.out.println("Drag dropped on " + item);
                    int valueToMove = Integer.parseInt(dragEvent.getDragboard().getString());
                    TreeItem<DynamicTreeNodeModel> itemToMove = search(parentTree.getRoot(), valueToMove);
                    TreeItem<DynamicTreeNodeModel> newParent = search(parentTree.getRoot(), item);
                    // Remove from former parent.
                    itemToMove.getParent().getChildren().remove(itemToMove);
                    // Add to new parent.
                    newParent.getChildren().add(itemToMove);
                    newParent.setExpanded(true);
                    dragEvent.consume();
                }
            });
        }

        private TreeItem<DynamicTreeNodeModel> search(final TreeItem<DynamicTreeNodeModel> currentNode, final int valueToSearch) {
            TreeItem<DynamicTreeNodeModel> result = null;
            if (currentNode.getValue() == valueToSearch) {
                result = currentNode;
            } else if (!currentNode.isLeaf()) {
                for (TreeItem<DynamicTreeNodeModel> child : currentNode.getChildren()) {
                    result = search(child, valueToSearch);
                    if (result != null) {
                        break;
                    }
                }
            }
            return result;
        }
        private DynamicTreeNodeModel item;

        @Override
        protected void updateItem(DynamicTreeNodeModel item, boolean empty) {
            super.updateItem(item, empty);
            this.item = item;
            String text = (item == null) ? null : item.toString();
            setText(text);
        }
    }
}

我试图实现这个例子,但我在这里遇到了一个问题:

@Controller
public class FileUploadController {

    if (valueToMove != item) {
        // We accept the transfer!!!!!
        dragEvent.acceptTransferModes(TransferMode.MOVE);
    }
    ...............
    if (currentNode.getValue() == valueToSearch) {

我得到了不可比较的类型:DynamicTreeNodeModel和int

你能帮我解决这个问题吗?


共有1个答案

景永望
2023-03-14
匿名用户

请尝试以下操作:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package test;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeItem.TreeModificationEvent;
import javafx.scene.control.TreeView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class MainApp extends Application {

    private EventHandler<TreeModificationEvent<DynamicTreeNodeModel>> branchExpandedEventHandler;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Application.launch(MainApp.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Example Dynamic Tree");
        primaryStage.setResizable(true);
        final VBox box = new VBox();
        box.setFillWidth(false);
        Scene scene = new Scene(box);
        primaryStage.setScene(scene);
        box.getChildren().add(this.getExampleTree());
        primaryStage.show();
    }

    private TreeView<DynamicTreeNodeModel> getExampleTree() {
        DynamicTreeNodeModel rootNode = new RandomDynamicTreeNodeModel(null, "Root Node");

        TreeView<DynamicTreeNodeModel> treeView = new TreeView<DynamicTreeNodeModel>();

        treeView.setCellFactory(new Callback<TreeView<DynamicTreeNodeModel>, TreeCell<DynamicTreeNodeModel>>() {
            @Override
            public TreeCell call(TreeView<DynamicTreeNodeModel> param) {
                return new DnDCell(param);
            }
        });

        treeView.setPrefSize(1000, 750);
        TreeItem rootItem = new TreeItem(rootNode);
        branchExpandedEventHandler = new EventHandler<TreeModificationEvent<DynamicTreeNodeModel>>() {
            public void handle(TreeModificationEvent<DynamicTreeNodeModel> event) {
//                System.out.println("handling event " + event);
                TreeItem<DynamicTreeNodeModel> item = event.getTreeItem();
                populateTreeItem(item);
            }
        };

        rootItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
        treeView.setShowRoot(true);
        treeView.setRoot(rootItem);
        populateTreeItem(rootItem);
        rootItem.setExpanded(true);
//        treeView.setCellFactory(new LearningTreeCellFactory());
        return treeView;
    }

    private void populateTreeItem(TreeItem<DynamicTreeNodeModel> item) {
        DynamicTreeNodeModel node = item.getValue();
        boolean isPopulated = node.isPopulated();
        boolean areGrandChildrenPopulated = node.areChildenPopulated();
        node.populateToDepth(2);
        if (!isPopulated) {
            for (DynamicTreeNodeModel childNode : node.getChildren()) {
                TreeItem childItem = new TreeItem(childNode);
                childItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
                item.getChildren().add(childItem);
            }
        }
        if (!areGrandChildrenPopulated) {
            int i = 0;
            int size = node.getChildren().size();
            for (TreeItem childItem : item.getChildren()) {
                // get cooresponding node in the model
                if (i < size) {
                    DynamicTreeNodeModel childNode = node.getChildren().get(i);
                    i++;
                    for (DynamicTreeNodeModel grandChildNode : childNode.getChildren()) {
                        TreeItem grandChildItem = new TreeItem(grandChildNode);
                        grandChildItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
                        childItem.getChildren().add(grandChildItem);
                    }
                }
            }
        }
    }

    private static interface DynamicTreeNodeModel {

        public String getName();

        public void setName(String name);

        public boolean isPopulated();

        public boolean areChildenPopulated();

        public List<DynamicTreeNodeModel> getChildren();

        public void setChildren(List<DynamicTreeNodeModel> children);

        public DynamicTreeNodeModel getParent();

        public void setParent(DynamicTreeNodeModel parent);

        public void populateToDepth(int depth);

        @Override
        public String toString();
    }

    private static class RandomDynamicTreeNodeModel implements DynamicTreeNodeModel {

        private DynamicTreeNodeModel parent;
        private String name;
        private List<DynamicTreeNodeModel> children = null;

        public RandomDynamicTreeNodeModel(DynamicTreeNodeModel parent, String name) {
            this.parent = parent;
            this.name = name;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public void setName(String name) {
            this.name = name;
        }

        @Override
        public boolean isPopulated() {
            if (children == null) {
                return false;
            }
            return true;
        }

        @Override
        public boolean areChildenPopulated() {
            if (!this.isPopulated()) {
                return false;
            }
            for (DynamicTreeNodeModel child : this.children) {
                if (!child.isPopulated()) {
                    return false;
                }
            }
            return true;
        }

        @Override
        public List<DynamicTreeNodeModel> getChildren() {
            return children;
        }

        @Override
        public void setChildren(List<DynamicTreeNodeModel> children) {
            this.children = children;
        }

        @Override
        public DynamicTreeNodeModel getParent() {
            return parent;
        }

        @Override
        public void setParent(DynamicTreeNodeModel parent) {
            this.parent = parent;
        }
        private static Random random = new Random();

        @Override
        public void populateToDepth(int depth) {
            if (depth <= 0) {
                return;
            }
            if (children == null) {
                int num = random.nextInt(5);
                System.out.println("got a random number " + num);
                children = new ArrayList(num);
                for (int i = 0; i < num; i++) {
//                    children.add(new RandomDynamicTreeNodeModel(this, "child " + i));

                    children.add(new RandomDynamicTreeNodeModel(this, "child " + System.currentTimeMillis()));
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            int childDepth = depth - 1;
            for (DynamicTreeNodeModel child : children) {
                child.populateToDepth(childDepth);
            }
        }

        @Override
        public String toString() {
            return this.name;
        }
    }

    public class DnDCell extends TreeCell<DynamicTreeNodeModel> {

        private TreeView<DynamicTreeNodeModel> parentTree;

        public DnDCell(final TreeView<DynamicTreeNodeModel> parentTree) {
            this.parentTree = parentTree;
            // ON SOURCE NODE.
            setOnDragDetected(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    System.out.println("Drag detected on " + item);
                    if (item == null) {
                        return;
                    }
                    Dragboard dragBoard = startDragAndDrop(TransferMode.MOVE);
                    ClipboardContent content = new ClipboardContent();
                    content.put(DataFormat.PLAIN_TEXT, item.toString());
                    dragBoard.setContent(content);
                    event.consume();
                }
            });
            setOnDragDone(new EventHandler<DragEvent>() {
                @Override
                public void handle(DragEvent dragEvent) {
                    System.out.println("Drag done on " + item);
                    dragEvent.consume();
                }
            });
            // ON TARGET NODE.
//            setOnDragEntered(new EventHandler<DragEvent>() {
//                @Override
//                public void handle(DragEvent dragEvent) {
//                    System.out.println("Drag entered on " + item);
//                    dragEvent.consume();
//                }
//            });
            setOnDragOver(new EventHandler<DragEvent>() {
                @Override
                public void handle(DragEvent dragEvent) {
                    System.out.println("Drag over on " + item);
                    if (dragEvent.getDragboard().hasString()) {
                        String valueToMove = dragEvent.getDragboard().getString();
                        if (!valueToMove.matches(item.getName())) {
                            // We accept the transfer!!!!!
                            dragEvent.acceptTransferModes(TransferMode.MOVE);
                        }
                    }
                    dragEvent.consume();
                }
            });
//            setOnDragExited(new EventHandler<DragEvent>() {
//                @Override
//                public void handle(DragEvent dragEvent) {
//                    System.out.println("Drag exited on " + item);
//                    dragEvent.consume();
//                }
//            });
            setOnDragDropped(new EventHandler<DragEvent>() {
                @Override
                public void handle(DragEvent dragEvent) {
                    System.out.println("Drag dropped on " + item);
                    String valueToMove = dragEvent.getDragboard().getString();
                    TreeItem<DynamicTreeNodeModel> itemToMove = search(parentTree.getRoot(), valueToMove);
                    TreeItem<DynamicTreeNodeModel> newParent = search(parentTree.getRoot(), item.getName());
                    // Remove from former parent.
                    itemToMove.getParent().getChildren().remove(itemToMove);
                    // Add to new parent.
                    newParent.getChildren().add(itemToMove);
                    newParent.setExpanded(true);
                    dragEvent.consume();
                }
            });
        }

        private TreeItem<DynamicTreeNodeModel> search(final TreeItem<DynamicTreeNodeModel> currentNode, final String valueToSearch) {
            TreeItem<DynamicTreeNodeModel> result = null;
            if (currentNode.getValue().getName().matches(valueToSearch)) {
                result = currentNode;
            } else if (!currentNode.isLeaf()) {
                for (TreeItem<DynamicTreeNodeModel> child : currentNode.getChildren()) {
                    result = search(child, valueToSearch);
                    if (result != null) {
                        break;
                    }
                }
            }
            return result;
        }
        private DynamicTreeNodeModel item;

        @Override
        protected void updateItem(DynamicTreeNodeModel item, boolean empty) {
            super.updateItem(item, empty);
            this.item = item;
            String text = (item == null) ? null : item.toString();
            setText(text);
        }
    }
}

在这里,我比较了名称(与Ithachi的意见相同)并做了一些调整(检查您的< code>populateTreeItem(..)函数,并根据您的需要进行修改(如果目前不支持)..

为了避免重复的名字,我使用了系统。currentTimemillis作为节点名称的一部分。。

希望有帮助…

 类似资料:
  • 我有两个从服务器端源并排填充的treeview。 左边的treeview包含分组的权限。右边的treeview包含人。 我已经在drop事件中设置了规则,以防止用户将权限以外的任何内容拖动到除个人以外的任何内容: 到目前为止还好。不过,我确实希望能够将相同的权限拖动到多个人。剑道树视图在拖放操作上做一个“移动节点”。 如何防止源树上拖动的节点被移动?

  • 我有一个SWT树,它有图像和其他文本和多级子。现在我想拖动这个树节点,但我无法为此获得适当的传输类型。所以一旦我拖动,我就不会得到拖动的图像。是否有相同的默认传输类型可用。 我用了下面的转账,但没用-

  • 我试图拖动对象表示为PNG图像透明背景从AnchorPane到HBox。 我使用以下线条将图像设置为拖动视图: 对于不透明的背景图像,这一切都很好,但对于透明的图像,图像的背景是白色的,不透明度为“0.8”。 我尝试为节点拍摄快照: 但它不起作用,白色背景仍然存在。有没有其他方法可以让它像原始图像一样透明?

  • 我使用的是bootstrap treeview,它大部分工作正常,但是当我从菜单链接加载一个新页面时,我希望所选子节点的所有父节点都展开,有人知道怎么做吗? 谢谢 抢劫 这里有一些代码... 这是来自我的数据库的数组,可以很好地显示所有treeview项。。。 如果您查看数组中的ID127,您将注意到子级的“扩展”为true “状态:{“选中”:false,“禁用”:false,“扩展”:true

  • 树视图以分层视图显示文档。导航栏可让你快速地切换、插入或删除文档。 添加一个文档 在导航栏点击 或按 CTRL+N 来得到一个空白显示的文档。 输入所需的数据。 在导航栏点击 来保存文档。 【注意】如果你的集合是空的,你需要点击 来添加新字段。 编辑一个文档 前往你想编辑的文档。 点击要修改的字段名、值或类型。 在导航栏点击 来应用更改。 添加一个字段或一个项目 前往你想编辑的文档。 点击 来添加

  • 树视图以分层视图显示文档。导航栏可让你快速地切换、插入或删除文档。 添加一个文档 在导航栏点击 或按 COMMAND-+ 来得到一个空白显示的文档。 输入所需的数据。 在导航栏点击 来保存文档。 【注意】如果你的集合是空的,你需要点击 来添加新字段。 编辑一个文档 前往你想编辑的文档。 点击要修改的字段名、值或类型。 在导航栏点击 来应用更改。 添加一个字段或一个项目 前往你想编辑的文档。 点击