当我从Jtree中删除节点时,有时其他节点的jlabel不会刷新,文本被切断,因此显示三个点" ..."因为jlabel具有已删除的上一个节点的宽度,并且UI没有按照代码中的请求进行刷新。
我相信我正确管理节点并正确刷新用户界面,但我想我或者在代码中遗漏了某些内容,或者我完全做错了。我希望有人可以帮助我。
这是我的JTree的一个例子:
RootNode
ParentNodeA
ChildNodeA1
ChildNodeA2
ParentNodeB
ChildNodeB1_hithere
ChildNodeB2_imlost
ChildNodeB3_whoisthere
ChildNodeB4_dude
说我想添加节点" ChildNodeA3"到ParentNodeA。我通过提供JTree对象和一个字符串数组来调用函数addNodeToTree(),该字符串数组包含我想要新节点的路径,即:[RootNode,ParentNodeA]。
当我想删除一个节点时,说" ChildNodeB2_imlost",我调用了函数removeNodeFromTree(tree,[RootNode,ParentNodeB,ChildNodeB2_imlost]),我提供了jtree对象和一个完整的字符串数组要删除的节点的路径。
当我删除节点时,其他节点jlabels UI不会在新位置刷新,并且仍然保持其原始宽度位于其最后位置,现在不会环绕新位置的文本,因此显示三个点。
在下面的代码中,我根据需要验证路径并扩展父节点,以便找到要删除的节点。删除节点后,我使用树模型重新加载已删除的节点的父节点以重新加载UI,但仍然无法正常工作。
public void removeNodeFromTree(JTree tree, String[] path)
{
TreePath treepath = null;
for (String section : path)
{
int row = (treepath == null ? 0 : tree.getRowForPath(treepath));
// Expand the current tree path because it seems that if the current tree
// path is collapsed, getNextMatch() returns null even though the node we are
// looking for exists. Not sure if this is a bug in JTree.getNextPath() or if that is the intent.
tree.fireTreeExpanded(treepath);
treepath = tree.getNextMatch(section, row, Position.Bias.Forward);
// Return if the path provided doesn't exist.
if ( treepath == null )
{
return;
}
}
// Get the target node to be removed.
DefaultMutableTreeNode targetNode (DefaultMutableTreeNode)treepath.getLastPathComponent();
// Get the parent of the target node.
DefaultMutableTreeNode nParent = (DefaultMutableTreeNode)targetNode.getParent();
targetNode.removeFromParent();
// Get the tree model from the JTree object and refresh the parent node.
DefaultTreeModel tModel = (DefaultTreeModel)tree.getModel();
tMode.reload(nParent);
}
public void addNodeToTree(JTree tree, String[] path, Object userObject)
{
TreePath treepath = null;
for (String section : path)
{
int row = (treepath == null ? 0 : tree.getRowForPath(treepath));
// Expand the current tree path because it seems that if the current tree
// path is collapsed, getNextMatch() returns null even though the node we are
// looking for exists. Not sure if this is a bug in JTree.getNextPath() or if that is the intent.
tree.fireTreeExpanded(treepath);
treepath = tree.getNextMatch(section, row, Position.Bias.Forward);
// Return if the path provided doesn't exist.
if ( treepath == null )
{
return;
}
}
// Get the parent of the new node to be added.
DefaultMutableTreeNode nParent = (DefaultMutableTreeNode)targetNode.getParent();
nParent.add(new DefaultMutableTreeNode(userObject));
// Get the tree model from the JTree object and refresh the parent node.
DefaultTreeModel tModel = (DefaultTreeModel)tree.getModel();
tMode.reload(nParent);
}
有什么想法吗?先谢谢你。
答案 0 :(得分:1)
好的,所以在查看了trashgod提供的关于动态更改树的链接后,我意识到我之前添加和删除节点的方式不正确。我发现,使用getNextMatch()方法时,prefix参数不用于查找其值的精确匹配。它用于查找相对匹配或接近前缀值的内容。这对我来说是个大问题,因为我的节点名称相似,所以这种方法会失败,即:如果我在搜索NodeA并且NodeAB在JTree中的NodeA之前,那么我会得到NodeAB,因为前缀是&#34 ; NodeA上"和NodeAB有" NodeA"在里面。 另一个问题是我没有使用树模型来插入节点或删除JTree中的节点。似乎添加或删除节点的正确方法是通过树模型。这将在添加或删除JTree中的节点时执行正确的UI更新。
以下是我编写的新代码,它将以正确的方式添加和删除JTree中的节点:
在这段代码中我假设我有一个用户定义的对象,当调用toString()时,它将返回一个表示该对象的字符串。此用户定义的对象将添加到addNodeToTree()中的节点。
// Adds a node to a JTree providing the name of the parent node that the new node
// belongs to.
private void addNodeToTree(Object newObject, String category, JTree tree) {
DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode)treeModel.getRoot();
// BreadFirst means it searches by top nodes first. It'll start with the root node,
// then iterate thru the children of the root node and so on.
Enumeration en = rootNode.breadthFirstEnumeration();
while ( en.hasMoreElements() ) {
DefaultMutableTreeNode categoryNode = (DefaultMutableTreeNode)en.nextElement();
// Get the user defined object.
Object categoryObject = categoryNode.getUserObject();
// Check if node matches the category that the new node belongs to and if it does, then
// add the new node in this category node.
if ( categoryObject.toString().equals(category) ) {
// Create a new node.
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(newObject);
// Use the tree model to insert the new node. This will take care of the UI updates.
treeModel.insertNodeInto(newNode, categoryNode, categoryNode.getChildCount());
// Exit out of the loop.
break;
}
}
}
// Iterates thru all the nodes in the JTree and removes the node that
// matches the string node_name.
private void removeNodeFromTree(String node_name, JTree tree) {
DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode)treeModel.getRoot();
// DepthFirst means it provides the very last child nodes and work its way up to the root node.
Enumeration en = rootNode.depthFirstEnumeration();
while ( en.hasMoreElements() ) {
// Get a reference to a node in the tree to see if it is the target node.
DefaultMutableTreeNode targetNode = (DefaultMutableTreeNode)en.nextElement();
// Get the virtual component object of the target node.
Object objectTargetNode = targetNode.getUserObject();
// If the target node matches the node_name string, then remove the node using
// the tree model to perform the removal.
if ( objectTargetNode.toString().equals(node_name) ) {
treeModel.removeNodeFromParent(targetNode);
// Exit out of the loop.
break;
}
}
}
我希望这可以帮助遇到同样问题的人。