【问题标题】:How to work my tree structure into a Jtree?如何将我的树结构工作到 Jtree 中?
【发布时间】:2013-01-29 21:05:25
【问题描述】:

首先我应该说我正在使用 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;
    }
}

【问题讨论】:

  • 重建它!不这样做是一个陷阱。一开始似乎更容易,但现在你有一个适当的数据模型,你可以添加自己的逻辑。切换到摇摆模式实际上会退后一步。
  • 我不知道您的全部要求,但为了创建一个简单的 JTree,您可以在此处 (apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-JTree.html) 找到一个演示示例。由于您已经有了一个包含数据的结构,您可以将processHierarchy 方法“调整”到您自己的数据。
  • @flup 您是否建议实施树模型并基于该结构进行重建? @Ivo 谢谢!

标签: java swing treeview jtree


【解决方案1】:

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

是的。 FileTreeModel,引用here,就是一个例子。正如How to Use Trees: Creating a Data Model 中所述,“您只需实现树模型,以便它使用现有数据结构中的信息。”

【讨论】:

    【解决方案2】:

    希望这节课对你有所帮助

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

    【讨论】:

      【解决方案3】:

      希望这节课对你有所帮助

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

      【讨论】:

        猜你喜欢
        • 2013-09-04
        • 2019-05-28
        • 1970-01-01
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多