簡體   English   中英

來自ArrayList的JTree不顯示節點

[英]JTree from ArrayList not displaying nodes

我有一個自定義數據結構,它基本上只是一個ArrayLists的命名ArrayList。 與XML類似。

(已刪除非密碼)

    public class Element extends ArrayList<Element> {
        private String name;


        public Element(String n){

            name = n;
        }

        @Override
        public String toString(){

            return name;
        }
    }

我正在嘗試使用自定義TreeModel類在JTree中顯示此內容。 但是,JTree不會正確顯示。 在分支的末尾僅顯示一個節點,當選擇子節點時,它顯示最后一個子節點,但是當未選中時,它顯示第一個子節點,但仍在分支的末尾。

捕獲

通過廣泛的調試,我可以看到它讀取了所有子節點並正確計數,只是不顯示它們。 我懷疑它們全都顯示在彼此的頂部,但不知道為什么或怎么做。

任何贊賞。

public class TestModel implements TreeModel{

    Element data;

    TestModel(){      
        data = new Element("data");

        data.add(new Element("One"));
        data.add(new Element("Two"));
        data.add(new Element("Three"));
        data.add(new Element("Four"));
        data.add(new Element("Five"));
    }

    @Override
    public Object getRoot() {
        return data;
    }

    @Override
    public Object getChild(Object parent, int index) {

        if(parent instanceof Element){
            Element p = (Element)parent;
            Element child = p.get(index);

            return child;
        }

        return null;
    }

    @Override
    public int getChildCount(Object parent) {

        if(parent instanceof Element){
            Element e = (Element)parent;
            return e.size();
        }

        return 0;
    }

    @Override
    public int getIndexOfChild(Object parent, Object child) {

        if(parent instanceof Element){
            Element e = (Element)parent;

            return e.indexOf(child);
        }

        return -1;

    }

    @Override
    public boolean isLeaf(Object node) {
        //List<? super ArrayList> d = (List<? super ArrayList>) node;

        if(node instanceof Element){
            Element e = (Element)node;
            return e.isEmpty();
        }

        return true;
    }
}

問題是您使用Element類並將其從ArrayList擴展的方式。 這歸結為如何從ArrayList (或AbstractList ,更准確地說)計算hashcode

hashcode是根據ArrayList的元素計算得出的,對於所有子Elementhashcode均為0 ,導致所有子Elementhashcode均為1 ,這會導致List查找和唯一標識元素的問題。

我個人將創建一個Node類,其中包含一個List成員,並提供可以與TreeModel使用或僅使用TreeNode其他功能。

例如...

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

public class TestTree {

    public static void main(String[] args) {
        new TestTree();
    }

    public TestTree() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JTree tree = new JTree(new TestModel());

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(tree));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestModel implements TreeModel {

        Element data;

        TestModel() {
            data = new Element("data");

            data.add(new Element("One"));
            data.add(new Element("Two"));
            data.add(new Element("Three"));
            data.add(new Element("Four"));
            data.add(new Element("Five"));
        }

        @Override
        public Object getRoot() {
            return data;
        }

        @Override
        public Object getChild(Object parent, int index) {

            System.out.println("GetChild from " + parent + " @ " + index);

            if (parent instanceof Element) {
                Element p = (Element) parent;
                Object child = p.getChildAt(index);

                System.out.println("child = " + child);
                return child;
            }

            return null;
        }

        @Override
        public int getChildCount(Object parent) {

            if (parent instanceof Element) {
                Element e = (Element) parent;
                System.out.println("childCount = " + parent + "; " + e.getChildCount());
                return e.getChildCount();
            }

            return 0;
        }

        @Override
        public int getIndexOfChild(Object parent, Object child) {

            if (parent instanceof Element && child instanceof Element) {
                Element e = (Element) parent;

                System.out.println("indexOf " + child + " in " + parent + " is " + e.getIndex((Element)child));
                return e.getIndex((Element)child);
            }

            return -1;

        }

        @Override
        public boolean isLeaf(Object node) {
            //List<? super ArrayList> d = (List<? super ArrayList>) node;

            if (node instanceof Element) {
                Element e = (Element) node;
                System.out.println("isLeaf " + e + "; " + (e.getChildCount() == 0));
                return e.getChildCount() == 0;
            }

            return true;
        }

        @Override
        public void valueForPathChanged(TreePath path, Object newValue) {

        }

        @Override
        public void addTreeModelListener(TreeModelListener l) {

        }

        @Override
        public void removeTreeModelListener(TreeModelListener l) {

        }
    }

    public static class Element implements TreeNode {

        private List<Element> nodes;
        private Element parent;

        private String name;

        public Element(String n) {

            nodes = new ArrayList<>(25);
            name = n;
        }

        @Override
        public String toString() {

            return name;
        }

        protected void setParent(Element parent) {
            this.parent = parent;
        }

        public void add(Element node) {
            node.setParent(this);
            nodes.add(node);
        }

        public void remove(Element node) {
            node.setParent(null);
            nodes.remove(node);
        }

        @Override
        public TreeNode getChildAt(int childIndex) {
            return nodes.get(childIndex);
        }

        @Override
        public int getChildCount() {
            return nodes.size();
        }

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

        @Override
        public int getIndex(TreeNode node) {
            return nodes.indexOf(node);
        }

        @Override
        public boolean getAllowsChildren() {
            return true;
        }

        @Override
        public boolean isLeaf() {
            return nodes.isEmpty();
        }

        @Override
        public Enumeration children() {
            return Collections.enumeration(nodes);
        }
    }
}

或者,您可以只使用一種預定義的TreeNode類,例如DefaultMutableTreeNode

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM