gpt4 book ai didi

Java TreePath.equals() 麻烦

转载 作者:行者123 更新时间:2023-11-29 03:40:06 33 4
gpt4 key购买 nike

由于 TreePath 用于识别数据节点的方法,我无法让 Outline 控件(替代 TreeTable)处理数据对象树。

关键问题是TreePath的equals()方法是通过数据节点的equals()方法来判断数据树中的两个节点对象是否相同。 TreeModel.java 甚至评论了这个问题:

“一些实现可能会假设如果两个 TreePath 相等 [由 equals() 确定],它们标识相同的节点。如果不满足此条件,则可能会导致绘制问题和其他异常情况。”示例数据:

  • 一个
      • C
      • D
      • E
      • F
    • H
    • K

这里,两个“B”节点作为单独的节点可能被认为具有相等的值(因此 equals() 返回 true),但它们肯定不代表树中的相同节点。

好的,所以如果源数据对象已经实现了 equals() 来指示相等的 仅考虑节点本身的值,如果在特定父节点下出现多个具有相同值的节点,这会破坏 TreePath .在这种情况下,Outline 无法展开/折叠正确的相同值节点之一。

如果 TreePath.equals() 使用“==”而不是数据对象的 equals() 方法,这个问题就会得到解决。但是,由于库存 TreePath 与 TreeModel 等紧密相连,因此如何在不造成大量中断的情况下修复此行为并不明显。

是否有一些优雅的方式来获得正确的效果?

谢谢!

最佳答案

实际上,我认为问题出在您在TreeNode 中实现equals() 的方式。如果两个 TreeNode 表示相同的视觉节点,则在您的情况下,它们应该被视为相等。两个 TreeNode 可以表示相同的模型对象(例如模型对象 B)但仍然是不同的节点。

这是一个基于 DefaultMutableTreeNode 的简单演示(equals() 使用 Object.equals(Object) 默认实现 ==)。每 2 秒它会切换从节点 B1 到 B2 的选择:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

public class TestTreeNodes {

public static class SomeModelNode {
private String value;

public SomeModelNode(String value) {
super();
this.value = value;
}

public String getValue() {
return value;
}

}

public class MyTreeCellRenderer extends DefaultTreeCellRenderer {

@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
Component cell = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
if (treeNode.getUserObject() instanceof SomeModelNode) {
setText(((SomeModelNode) treeNode.getUserObject()).getValue());
}
}
return cell;
}
}

private JFrame f;
private JTree tree;
private DefaultMutableTreeNode nodeA;
private DefaultMutableTreeNode nodeB1;
private DefaultMutableTreeNode nodeB2;
private DefaultMutableTreeNode nodeC;
private DefaultMutableTreeNode nodeD;
private DefaultMutableTreeNode nodeE;
private DefaultMutableTreeNode nodeF;
private DefaultMutableTreeNode nodeH;
private DefaultMutableTreeNode nodeK;

private boolean showingB1 = false;

protected void initUI() {
tree = new JTree(getModel());
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
ToolTipManager.sharedInstance().registerComponent(tree);
tree.setCellRenderer(new MyTreeCellRenderer());
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.add(new JScrollPane(tree));
f.pack();
f.setVisible(true);
Timer t = new Timer(2000, new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
if (!showingB1) {
tree.getSelectionModel().setSelectionPath(getPathForNode(nodeB1));
} else {
tree.getSelectionModel().setSelectionPath(getPathForNode(nodeB2));
}
showingB1 = !showingB1;
}
});
t.start();

}

private TreePath getPathForNode(TreeNode node) {
List<TreeNode> nodes = new ArrayList<TreeNode>();
TreeNode current = node;
while (current != null) {
nodes.add(current);
current = current.getParent();
}
Collections.reverse(nodes);
return new TreePath(nodes.toArray(new Object[nodes.size()]));
}

private TreeModel getModel() {
SomeModelNode a = new SomeModelNode("A");
SomeModelNode b = new SomeModelNode("B");
SomeModelNode c = new SomeModelNode("C");
SomeModelNode d = new SomeModelNode("D");
SomeModelNode e = new SomeModelNode("E");
SomeModelNode f = new SomeModelNode("F");
SomeModelNode h = new SomeModelNode("H");
SomeModelNode k = new SomeModelNode("K");
nodeA = new DefaultMutableTreeNode(a);
nodeB1 = new DefaultMutableTreeNode(b);
nodeB2 = new DefaultMutableTreeNode(b);
nodeC = new DefaultMutableTreeNode(c);
nodeD = new DefaultMutableTreeNode(d);
nodeE = new DefaultMutableTreeNode(e);
nodeF = new DefaultMutableTreeNode(f);
nodeH = new DefaultMutableTreeNode(h);
nodeK = new DefaultMutableTreeNode(k);
// Children of A
nodeA.add(nodeB1);
nodeA.add(nodeB2);
nodeA.add(nodeH);
nodeA.add(nodeK);
// Children of B1
nodeB1.add(nodeC);
nodeB1.add(nodeD);
// Children of B2
nodeB2.add(nodeE);
nodeB2.add(nodeF);
DefaultTreeModel model = new DefaultTreeModel(nodeA);
return model;
}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new TestTreeNodes().initUI();
}
});
}

}

关于Java TreePath.equals() 麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13561142/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com