1

首先,我应该说我正在使用 netbeans,而且我是整个 java GUI 游戏的新手。

所以,我的问题是我创建了自己的特定于我的项目的树结构,我现在想使用我的结构来构造 JTree。

我正在阅读 Jtree 的主题,据我了解,我需要在我的结构中实现 TreeModel 接口。我还读到的另一种方法是使用 DefaultMutableTreeNode 但我找不到任何使用它的示例对我来说很清楚。

现在我已经构建了整个树结构并填充了数据,并试图避免重建它。如何将我的树实现为 Jtree?

package models;

import java.util.ArrayList;
import java.util.List;


public class IngredientTree {

   private Node root;


    public IngredientTree(){
        root = new Node();
    }
    public IngredientTree(Node rootData) {
        root = rootData;
    }

    public void setRoot(Node n){
        root = n;
    }

    public Node getRoot(){
        return root;
    }

    public void addToTree(Ingredient i){
        if(root.getData().getName()=="") // Then it must be the root 
            root.setData(i);
        else
            addToTree(root,i);
    }
    private void addToTree(Node n, Ingredient i){
        if(isFirstAdd(n)) //Has no parent and no children
            n.addChild(new Node(i,n));
        else if(n.hasChildren()){ //Has parent and children
            if(!inChildren(n,i)){
                if(inNode(n,i))
                    n.addChild(new Node(i,n));
            }
            else{
                for(Node child : n.getChildren()){
                    addToTree(child,i);
                }
            }
        }
        else{ //Has parent but no children
            n.addChild(new Node(i,n));
        }
    }
    private boolean isFirstAdd(Node n){
        return(!n.hasParent() && !n.hasChildren());
    }
    private boolean inChildren(Node n,Ingredient i){
        for(Node child : n.getChildren()){
            if(inNode(child,i))
                return true;
        }
        return false;
    }

    private boolean inNode(Node n,Ingredient i){
        return(i.getStartIndex() > n.getData().getStartIndex() &&
                i.getEndIndex() < n.getData().getEndIndex());
    }

    public int countIngredients(){
        return countIngredients(this.getRoot());
    }

    private int countIngredients(Node r){
        int count = 0;
        if(!r.hasChildren()){
            return 1;
        }else{
            for(Node child: r.getChildren()){
                count += countIngredients(child);
            }
        }
        return count;
    }
}
4

3 回答 3

2

您是否建议实施树模型并基于该结构进行重建?

是的。,这里FileTreeModel引用,是一个例子。如如何使用树:创建数据模型中所述,“您只需要实现树模型,以便它使用现有数据结构中的信息。”

于 2013-01-30T08:36:17.833 回答
0

我希望这堂课能帮到你

package dharm.mytasks.component;

import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import dharm.mytasks.ui.helper.CommonHelper;

public class Tree<T extends Object> extends JTree {
    private static final long serialVersionUID = 1L;

    public Tree(T rootUserObj){
        this(new TreeNode<>(rootUserObj));
    }

    public Tree(TreeNode<T> root) {
        super(root);

        this.setPreferredSize(new Dimension(150, 0));
//      this.setRootVisible(false);
        this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        this.setExpandsSelectedPaths(true);
    }

    @SuppressWarnings("unchecked")
    public TreeNode<T> getRoot() {
        return (TreeNode<T>) getModel().getRoot();
    }

    public void fillChildren(Consumer<TreeNode<T>> childFiller){
        getRoot().fillChildren(childFiller);
    }

    /** Loop for all nodes (deep=true) */
    public void forEachNodes(Consumer<TreeNode<T>> childConsumer){
        TreeNode<T> root = getRoot();
        childConsumer.accept(root);
        root.forEach(childConsumer, true);
    }

    public T getRootUserObject(){
        return getRoot().getUserObject();
    }

    public TreeNode<T> getSelectedNode(){
        @SuppressWarnings("unchecked")
        TreeNode<T> node = (TreeNode<T>) getSelectionModel().getSelectionPath().getLastPathComponent();
        return node;
    }

    public T getSelectedUserObject(){
        TreeNode<T> node = getSelectedNode();
        if(node != null /*&& node.isLeaf()*/) {
            return node.getUserObject();
        }
        return null;
    }

    public void setSelectedNode(TreeNode<T> node){
        setSelectionPath(new TreePath(node.getPath()));
    }

    public void onChange(Consumer<T> consumer){
        super.addTreeSelectionListener(evt->{
            TreePath selectedPath = evt.getNewLeadSelectionPath();
            if(selectedPath==null) return;
            @SuppressWarnings("unchecked")
            TreeNode<T> node = (TreeNode<T>) selectedPath.getLastPathComponent();
            if(node != null && node.isLeaf()) {
                T userObject = node.getUserObject();
                consumer.accept(userObject);
            }
        });
    }

    public void onMouseRightClickOnNode(BiConsumer<TreeNode<T>, MouseEvent> consumer){
        Tree<T> tree = this;
        CommonHelper.onMouseRightClick(tree, evt->{
            TreePath path = getPathForLocation(evt.getX(), evt.getY());
            if(path==null) return;
            tree.setSelectionPath(path);
            TreeNode<T> node = tree.getSelectedNode();

            consumer.accept(node, evt);
        });
    }

    public void showPopupOnRightClick(BiConsumer<MyJPopupMenu, TreeNode<T>> popupMenuItemFiller){
        this.onMouseRightClickOnNode((node,evt)->{
            MyJPopupMenu popup = new MyJPopupMenu();
            popupMenuItemFiller.accept(popup,node);
            popup.show(evt.getComponent(), evt.getX(), evt.getY());
        });
    }

    public static class TreeNode<T> extends DefaultMutableTreeNode {
        private static final long serialVersionUID = 1L;

        public TreeNode(T userObj){
            super(userObj);
        }

        /** @param userObj
         * @return child node
         */
        public TreeNode<T> addChild(T userObj) {
            TreeNode<T> child = new TreeNode<>(userObj);
            add(child);
            return child;
        }

        @Override
        public T getUserObject(){
            @SuppressWarnings("unchecked")
            T userObject = (T) super.getUserObject();
            return userObject;
        }

        @SuppressWarnings("unchecked")
        public List<TreeNode<T>> getChildren(){
            return (List<TreeNode<T>>) children;//.clone();
        }

        public void fillChildren(Consumer<TreeNode<T>> childFiller){
            if(getChildCount() != 0)
                super.removeAllChildren();
            childFiller.accept(this);
            forEach(child->child.fillChildren(childFiller), false);
        }

        /**
         * @param childConsumer
         * @param deep <code>true</code>=access all, <code>false</code>=first level children
         */
        public void forEach(Consumer<TreeNode<T>> childConsumer, boolean deep){
            getChildren().forEach(child->{
                childConsumer.accept(child);
                if(deep)
                    child.forEach(childConsumer, deep);
            });
        }

    }
}



public class CommonHelper {

    /**
     * @param comp component where listener should add
     * @param onRighClickConsumer
     */
    public static void onMouseRightClick(Component comp, Consumer<MouseEvent> onRighClickConsumer){
        comp.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(SwingUtilities.isRightMouseButton(e) && e.getClickCount()==1)
                    onRighClickConsumer.accept(e); //call on right click
            }
        });
    }
}
于 2018-12-20T06:06:32.950 回答
0

我希望这堂课能帮到你

package dharm.mytasks.component;

import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import dharm.mytasks.ui.helper.CommonHelper;

public class Tree<T extends Object> extends JTree {
    private static final long serialVersionUID = 1L;

    public Tree(T rootUserObj){
        this(new TreeNode<>(rootUserObj));
    }

    public Tree(TreeNode<T> root) {
        super(root);

        this.setPreferredSize(new Dimension(150, 0));
//      this.setRootVisible(false);
        this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        this.setExpandsSelectedPaths(true);
    }

    @SuppressWarnings("unchecked")
    public TreeNode<T> getRoot() {
        return (TreeNode<T>) getModel().getRoot();
    }

    public void fillChildren(Consumer<TreeNode<T>> childFiller){
        getRoot().fillChildren(childFiller);
    }

    /** Loop for all nodes (deep=true) */
    public void forEachNodes(Consumer<TreeNode<T>> childConsumer){
        TreeNode<T> root = getRoot();
        childConsumer.accept(root);
        root.forEach(childConsumer, true);
    }

    public T getRootUserObject(){
        return getRoot().getUserObject();
    }

    public TreeNode<T> getSelectedNode(){
        @SuppressWarnings("unchecked")
        TreeNode<T> node = (TreeNode<T>) getSelectionModel().getSelectionPath().getLastPathComponent();
        return node;
    }

    public T getSelectedUserObject(){
        TreeNode<T> node = getSelectedNode();
        if(node != null /*&& node.isLeaf()*/) {
            return node.getUserObject();
        }
        return null;
    }

    public void setSelectedNode(TreeNode<T> node){
        setSelectionPath(new TreePath(node.getPath()));
    }

    public void onChange(Consumer<T> consumer){
        super.addTreeSelectionListener(evt->{
            TreePath selectedPath = evt.getNewLeadSelectionPath();
            if(selectedPath==null) return;
            @SuppressWarnings("unchecked")
            TreeNode<T> node = (TreeNode<T>) selectedPath.getLastPathComponent();
            if(node != null && node.isLeaf()) {
                T userObject = node.getUserObject();
                consumer.accept(userObject);
            }
        });
    }

    public void onMouseRightClickOnNode(BiConsumer<TreeNode<T>, MouseEvent> consumer){
        Tree<T> tree = this;
        CommonHelper.onMouseRightClick(tree, evt->{
            TreePath path = getPathForLocation(evt.getX(), evt.getY());
            if(path==null) return;
            tree.setSelectionPath(path);
            TreeNode<T> node = tree.getSelectedNode();

            consumer.accept(node, evt);
        });
    }

    public void showPopupOnRightClick(BiConsumer<MyJPopupMenu, TreeNode<T>> popupMenuItemFiller){
        this.onMouseRightClickOnNode((node,evt)->{
            MyJPopupMenu popup = new MyJPopupMenu();
            popupMenuItemFiller.accept(popup,node);
            popup.show(evt.getComponent(), evt.getX(), evt.getY());
        });
    }

    /** Reload/refresh in GUI */
    public void reload(){
        ((DefaultTreeModel) getModel()).reload();
    }

    public static class TreeNode<T> extends DefaultMutableTreeNode {
        private static final long serialVersionUID = 1L;

        public TreeNode(T userObj){
            super(userObj);
        }

        /** @param userObj
         * @return child node
         */
        public TreeNode<T> addChild(T userObj) {
            TreeNode<T> child = new TreeNode<>(userObj);
            add(child);
            return child;
        }

        @Override
        public T getUserObject(){
            @SuppressWarnings("unchecked")
            T userObject = (T) super.getUserObject();
            return userObject;
        }

        @SuppressWarnings("unchecked")
        public List<TreeNode<T>> getChildren(){
            return (List<TreeNode<T>>) children;//.clone();
        }

        public void fillChildren(Consumer<TreeNode<T>> childFiller){
            if(getChildCount() != 0)
                super.removeAllChildren();
            childFiller.accept(this);
            forEach(child->child.fillChildren(childFiller), false);
        }

        /**
         * @param childConsumer
         * @param deep <code>true</code>=access all, <code>false</code>=first level children
         */
        public void forEach(Consumer<TreeNode<T>> childConsumer, boolean deep){
            getChildren().forEach(child->{
                childConsumer.accept(child);
                if(deep)
                    child.forEach(childConsumer, deep);
            });
        }

    }
}
于 2018-12-20T06:20:52.293 回答