Looking for how to traverse a JTree (can do that) and check to see each node to see if it's displayed (to the user) or not visible. Can't believe JTree doesn't have this function, maybe I'm missing something?
查找如何遍历JTree(可以这样做)并查看每个节点,以查看它是否显示(对用户)或不可见。真不敢相信JTree没有这个函数,也许我漏掉了什么?
2 个解决方案
#1
5
You must consider two different things:
你必须考虑两件不同的事情:
-
A node can become hidden by closing one of its parents. Even though the parent is visible on the screen, the child isn't. Use JTree.isVisible() for this.
一个节点可以通过关闭它的父节点来隐藏。即使父节点在屏幕上是可见的,子节点也不可见。使用JTree.isVisible()。
-
If the node is expanded, it can become hidden because it is scrolled out of the current viewport. This isn't handled in the JTree but in the JScrollPane which wraps the tree. To find out if a node is in the visible area of the viewport.
如果节点被展开,它可以被隐藏起来,因为它是从当前的viewport展开的。这不是在JTree中处理的,而是在包装树的JScrollPane中处理的。查找一个节点是否位于viewport的可见区域。
To find out if #2 is true, you must get the rectangle where the node is using JTree.getPathBounds(). Then, you must intersect this rectangle with the viewport (use scrollPane.getViewport().getViewRect()
. If nodeRect.intersects (viewRect)
returns true
, the node is visible.
要确定#2是否为真,必须获得节点使用JTree.getPathBounds()的矩形。然后,必须将这个矩形与viewport(使用scrollPane.getViewport(). getviewrect())相交。如果node .intersect (viewRect)返回true,则节点是可见的。
#2
2
Depending on your application, it may be more efficient to just look for the visible nodes, rather than iterating through all nodes in the TreeModel
and determining if each is visible. A sample function to perform this is shown below:
根据应用程序的不同,只需查找可见的节点,而不是遍历TreeModel中的所有节点并确定每个节点是否可见,可能会更有效。执行此操作的示例函数如下:
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class JTreeTools {
public static List<TreeNode> getVisibleNodes(JScrollPane hostingScrollPane, JTree hostingJTree){
//Find the first and last visible row within the scroll pane.
final Rectangle visibleRectangle = hostingScrollPane.getViewport().getViewRect();
final int firstRow = hostingJTree.getClosestRowForLocation(visibleRectangle.x, visibleRectangle.y);
final int lastRow = hostingJTree.getClosestRowForLocation(visibleRectangle.x, visibleRectangle.y + visibleRectangle.height);
//Iterate through each visible row, identify the object at this row, and add it to a result list.
List<TreeNode> resultList = new ArrayList<TreeNode>();
for (int currentRow = firstRow; currentRow<=lastRow; currentRow++){
TreePath currentPath = hostingJTree.getPathForRow(currentRow);
Object lastPathObject = currentPath.getLastPathComponent();
if (lastPathObject instanceof TreeNode){
resultList.add((TreeNode)lastPathObject);
}
}
return(resultList);
}
}
#1
5
You must consider two different things:
你必须考虑两件不同的事情:
-
A node can become hidden by closing one of its parents. Even though the parent is visible on the screen, the child isn't. Use JTree.isVisible() for this.
一个节点可以通过关闭它的父节点来隐藏。即使父节点在屏幕上是可见的,子节点也不可见。使用JTree.isVisible()。
-
If the node is expanded, it can become hidden because it is scrolled out of the current viewport. This isn't handled in the JTree but in the JScrollPane which wraps the tree. To find out if a node is in the visible area of the viewport.
如果节点被展开,它可以被隐藏起来,因为它是从当前的viewport展开的。这不是在JTree中处理的,而是在包装树的JScrollPane中处理的。查找一个节点是否位于viewport的可见区域。
To find out if #2 is true, you must get the rectangle where the node is using JTree.getPathBounds(). Then, you must intersect this rectangle with the viewport (use scrollPane.getViewport().getViewRect()
. If nodeRect.intersects (viewRect)
returns true
, the node is visible.
要确定#2是否为真,必须获得节点使用JTree.getPathBounds()的矩形。然后,必须将这个矩形与viewport(使用scrollPane.getViewport(). getviewrect())相交。如果node .intersect (viewRect)返回true,则节点是可见的。
#2
2
Depending on your application, it may be more efficient to just look for the visible nodes, rather than iterating through all nodes in the TreeModel
and determining if each is visible. A sample function to perform this is shown below:
根据应用程序的不同,只需查找可见的节点,而不是遍历TreeModel中的所有节点并确定每个节点是否可见,可能会更有效。执行此操作的示例函数如下:
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class JTreeTools {
public static List<TreeNode> getVisibleNodes(JScrollPane hostingScrollPane, JTree hostingJTree){
//Find the first and last visible row within the scroll pane.
final Rectangle visibleRectangle = hostingScrollPane.getViewport().getViewRect();
final int firstRow = hostingJTree.getClosestRowForLocation(visibleRectangle.x, visibleRectangle.y);
final int lastRow = hostingJTree.getClosestRowForLocation(visibleRectangle.x, visibleRectangle.y + visibleRectangle.height);
//Iterate through each visible row, identify the object at this row, and add it to a result list.
List<TreeNode> resultList = new ArrayList<TreeNode>();
for (int currentRow = firstRow; currentRow<=lastRow; currentRow++){
TreePath currentPath = hostingJTree.getPathForRow(currentRow);
Object lastPathObject = currentPath.getLastPathComponent();
if (lastPathObject instanceof TreeNode){
resultList.add((TreeNode)lastPathObject);
}
}
return(resultList);
}
}