gpt4 book ai didi

java - 删除/替换独生子后 JTree.expandPath 的奇怪问题

转载 作者:行者123 更新时间:2023-11-29 03:36:44 24 4
gpt4 key购买 nike

我想出了这个 SSCCE 来重现我在一个更大的程序中遇到的一些奇怪的行为:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

public class TreeExpandTest {

private JFrame frame;

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TreeExpandTest window = new TreeExpandTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

public TreeExpandTest() {
initialize();
}

private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
final JTree tree = new JTree(root);
tree.setShowsRootHandles(true);
final DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
final DefaultMutableTreeNode level1 = new DefaultMutableTreeNode("Level 1");
root.add(level1);
DefaultMutableTreeNode level2a = new DefaultMutableTreeNode("Level 2a");
level1.add(level2a);

final TreeNode[] nodes = model.getPathToRoot(level1);
tree.expandPath(new TreePath(nodes));

frame.getContentPane().add(tree, BorderLayout.CENTER);

JButton btnDoStuff = new JButton("Remove 2a, replace with 2b");
frame.getContentPane().add(btnDoStuff, BorderLayout.SOUTH);
btnDoStuff.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
level1.remove(0);
int[] removed = {0};
model.nodesWereRemoved(level1, removed, null);

DefaultMutableTreeNode level2b = new DefaultMutableTreeNode("Level 2b");
level1.insert(level2b, 0);
int[] inserted = {0};
model.nodesWereInserted(level1, inserted);

//tree.collapsePath(new TreePath(nodes));
tree.expandPath(new TreePath(nodes));
}
});
}
}

要完全理解问题,请按以下步骤进行:

  1. 启动程序。
  2. 点击底部的按钮。这应该 (i) 删除“Level 2a”,然后 (ii) 将其替换为“Level 2b”,最后 (iii) 重新展开“Level 1”节点,以便新插入的替换项可见。
  3. 点击后,请注意“Level 1”在应该展开时折叠了。
  4. 真正奇怪的地方在于:单击“Level 1”前面的 handle 将其展开。请注意,没有任何反应!再次点击它,它最终会展开。这种奇怪的行为让我相信它实际上是从一开始就被扩展的,但不知何故绘制不正确。我不知道有什么方法可以调用重绘树,而且我相信我正在正确调用 nodesWereInserted 方法,这真的是我所能做的,对吧?

我找到了“解决”问题的解决方法,但不能满足我的好奇心。

  1. 取消源代码中倒数第二行的注释,然后启动程序并再次按下按钮。请注意,它现在运行良好。

问题仍然存在……出了什么问题,为什么需要我的解决方法?为什么我需要先折叠树,然后再告诉它我要展开它?

编辑添加:只有在我移除/替换独生子女时才会发生这种情况。如果有多个 child 并且我删除/替换使得 parent 永远不会没有 child ,那么每件事都会按预期进行。

最佳答案

通知不正确,必须是:

level1.remove(0);
int[] removed = {0};
Object[] children = new Object[]{level2a};
model.nodesWereRemoved(level1, removed, children);

注意子数组而不是 null

顺便说一句,我建议尽可能使用模型 api 来修改节点/结构(相对于更改其脚下的节点)。对于单个节点的更改,上面的内容是:

model.removeNodeFromParent(level2a);
DefaultMutableTreeNode level2b = new DefaultMutableTreeNode("Level 2b");
model.insertNodeInto(level2b, level1, 0);

关于java - 删除/替换独生子后 JTree.expandPath 的奇怪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15132937/

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