【问题标题】:How to get JTree expanded?如何让 JTree 扩展?
【发布时间】:2010-06-02 08:03:25
【问题描述】:

我有一个带有多个屏幕的向导,用户必须在其中填写他/她的详细信息以进行进一步处理。在第二个屏幕上,我有一个带有三个单选按钮的单选组,这些单选按钮可以启用其他元素。要继续,用户必须选择其中之一。当用户选择第三个按钮时,单选JTree 填充数据启用,用户必须从中选择一个选项。然后用户必须按“下一步”才能进入下一个屏幕。他\她选择的选项存储为TreePath。到目前为止一切顺利。

我的问题如下。如果用户想从下一个屏幕返回到带有JTree 的屏幕,我想为他\她提供JTree 扩展为已选择的选项并突出显示该选项。但是,无论我为此尝试做什么(expandPathscrollPathToVisibleaddSelectionPathmakeVisible 的任何组合)总是为我提供一棵折叠的树。我尝试扩展叶子和节点。我的代码如下所示:

rbProcessJTree.setSelected(isProcessJTree());

if (null != getSelectedTablePath()){
    trTables.addSelectionPath(getSelectedTablePath());
    trTables.expandPath(getSelectedTablePath());
    trTables.scrollPathToVisible(getSelectedTablePath());
}

当调用setSelected() 时,将调用启用JTree 的状态更改侦听器。模型在表单初始化期间加载。

每次在屏幕之间切换时,我都会保存前一个屏幕的输入数据并进行处理。然后,当我需要打开前一个屏幕时,我从下一个屏幕保存数据,处理它,将数据加载到这个屏幕并显示它。所以每次屏幕都是从头开始生成的。

您能否解释一下,要在新创建的表单中扩展JTree,并加载数据模型并提供选择路径,必须执行哪些操作顺序?

【问题讨论】:

标签: java swing jtree


【解决方案1】:

这是我用来记录 JTree 中扩展和选定路径的一些代码。您可以在 Next 和 Back 页面之间记录状态内容。

// record expanded nodes to reinstate later; 
TreePath rootPath= new TreePath(objectWeKnowIsAtRoot);

Enumeration<TreePath> expandedPaths = tree.getExpandedDescendants(rootPath);

// record current-selection - it's OK if it's null
TreePath selectedPath = tree.getSelectionPath();


// ******* do stuff that may, and often will, modify our tree content ********


// restore valid expansion paths (some may - correctly - have been removed in modifications)
while (expandedPaths != null && expandedPaths.hasMoreElements())
{
    TreePath path = expandedPaths.nextElement();
    if (isPathValid(path))
    {
        tree.expandPath(path);
    }
}

// restore selected path, if apt
if (isPathValid(selectedPath))
{
    tree.setSelectionPath(selectedPath);
}

上面使用的isValidPath()方法就是基于这个:

http://forums.sun.com/thread.jspa?threadID=567157&tstart=38085

【讨论】:

  • 我已经尝试过这种方法,但它也不起作用。不知道原因。后来看到枚举中返回的路径具有随机顺序,将它们转换为 ArrayList 并从根开始排序,而不是尝试使用它。没有机会。为所选路径本身添加了 expandPath()。没门。没有想法。不过感谢您的回复。顺便说一句,当我调试它时,我看到我的选择路径 isVisible() 为真,但 isExpanded() 为假。有帮助吗?
  • 嗯;填充数据后,您确定要进行选择/扩展吗?您可以尝试在您的向导中添加一个“调试此”按钮,当按下该按钮时,会进行选择/扩展,让您有机会在视觉上确认所有数据都存在并且首先正确?
  • 我会在一个小时左右完成当前任务后尝试。但是,isPathValid() 在调试时总是返回 true,因此 expandPath() 方法会在您的算法中执行。这应该意味着数据已经被填充,不是吗?我在初始化表单时填充数据模型。只有在那之后,我才尝试用它执行一些操作。也许必须对我的单选按钮的状态更改侦听器进行探索。在我进入树处理方法之前它会触发几次。
  • 当侦听器多次触发时,我在调试大量 Swing 代码时遇到了问题。绝对尝试“调试我”按钮,也可能值得使用 log4j 或 System.out 来确定它经历了多少完整的“周期”,例如您可能会发现事情在第一次运行时运行正常,但实际上它们在第二次运行时被消灭/失效?
  • 我添加了按钮,还使 JTree 始终启用以防止状态更改侦听器可能产生的影响。然而,没有变化。还有其他建议吗?
【解决方案2】:

如果您使用的是DefaultMutableTreeNode,您可以随时使用Enumeration 来搜索您想要的TreeNode。如果getExpandsSelectedPaths() 为真,那么setSelectionPath() 应该可以工作。

编辑:我想更像是使用来自DefaultMutableTreeNodeEnumeration

JTree tree = new JTree();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
...
private TreePath find(DefaultMutableTreeNode root, String s) {
    Enumeration<DefaultMutableTreeNode> e = root.depthFirstEnumeration();
    while (e.hasMoreElements()) {
        // return match
    }
    return null;
}

那么你可以这样做:

TreePath path = find(root, "pizza");
tree.setSelectionPath(path);
tree.scrollPathToVisible(path);

【讨论】:

  • 列表 tpa = treeStorage.getExpandedPathsList(); if (null != tpa){ Collections.sort(tpa, new TreePathComparator()); for (TreePath t : tpa){ if (isPathValid(t)){ trTables.expandPath(t); } } } if (isPathValid(treeStorage.getSelectedTablePath())){ trTables.setSelectionPath(treeStorage.getSelectedTablePath()); System.out.println("展开:" +trTables.getExpandsSelectedPaths());这段代码返回真。然而,树还是倒塌了。枚举以随机顺序返回结果,无法重置,因此我将其更改为 ArrayList。抱歉格式化。
猜你喜欢
  • 2011-08-05
  • 2016-02-12
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 2013-02-19
  • 2016-04-24
相关资源
最近更新 更多