[英]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
的元素計算得出的,對於所有子Element
, hashcode
均為0
,導致所有子Element
的hashcode
均為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.