Dynamic JTree 和 SwingUtilities.invokeLater() 不执行任何操作
为了创建我的动态 JTree,我正在阅读 这个网站在章节“4.2 OutlineNode.java”
现在我已经实现了它,并认识到在 GUI 线程中加载数据需要很长时间并且也很难看。因此,我添加了一个线程来扩展子级,然后将 TreeNode
元素添加到树中。
private void getChildNodes() {
areChildrenDefined = true;
Thread t = new Thread(new Runnable()
{
@Override
public void run() {
System.out.println("Expand");
final List<DECTTreeNode> listNodes = new ArrayList<DECTTreeNode>();
if (castNode().canExpand())
{
for(DECTNode crt : castNode().getChildren())
{
DECTTreeNode treeNode = new DECTTreeNode(crt);
listNodes.add(treeNode);
}
try {
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run() {
System.out.println(listNodes.size());
for (DECTTreeNode crt : listNodes)
{
add(crt); // <==== Adds the node to the JTree
}
}
});
//}).run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
t.start();
}
没有线程,它可以毫无问题地工作。如果我添加线程并将 add
-调用放入 SwingUtilities.invokeAndWait(...)
中,子级似乎已展开,但它们在树。
我已经在树上尝试了 revalidate()
和 repaint()
- 没有任何效果。
知道如何使这些元素可见吗?
先感谢您。
To create my dynamic JTree, I was reading the tutorial about Dynamic JTrees on this website in chapter "4.2 OutlineNode.java"
Now I have implemented it and recognize that loading the data in the GUI thread takes long and is ugly as well. Therefore I added a thread which expands the children and then adds the TreeNode
element to the tree.
private void getChildNodes() {
areChildrenDefined = true;
Thread t = new Thread(new Runnable()
{
@Override
public void run() {
System.out.println("Expand");
final List<DECTTreeNode> listNodes = new ArrayList<DECTTreeNode>();
if (castNode().canExpand())
{
for(DECTNode crt : castNode().getChildren())
{
DECTTreeNode treeNode = new DECTTreeNode(crt);
listNodes.add(treeNode);
}
try {
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run() {
System.out.println(listNodes.size());
for (DECTTreeNode crt : listNodes)
{
add(crt); // <==== Adds the node to the JTree
}
}
});
//}).run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
t.start();
}
Without the thread it works without problems. If I add the thread and put the add
-calls into a SwingUtilities.invokeAndWait(...)
, the children seem to be expanded, but they're not visible in the tree.
I've already tried revalidate()
and repaint()
on the tree - without any effect.
Any idea how to make these elements visible?
Thank you in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
检查您的 add() 方法是否触发正确的 TreeModelEvent
Check that your add() method fires the correct TreeModelEvent
要扩展 Walter +1 的建议,请从 JButton
addButton
调用Runnable#Thread
to expand suggestion by Walter +1, invoke
Runnable#Thread
from JButtonaddButton
评判我与否。这对我有用。 CustomTreeNode 是从 defaultMutableTreeNode 扩展而来的,并添加了一个自己编写的 ChildLoadedListener,当工厂加载子级时调用该监听器。 isExpanded 布尔值是为了避免无限循环。
工厂创建一个 SwingWorker 来加载子项并执行它。之后调用 ChilLoadedListener 并再次展开树。
希望这会有所帮助或至少帮助您思考您的问题;-)
编辑:
Jugde me or not. This works for me. CustomTreeNode is extended from defaultMutableTreeNode and has been added a selfwritten ChildLoadedListener which is called when the children have been loaded by the factory. The isExpanded boolean is to avoid a endless loop.
the factory creates a SwingWorker that loads the children and executes it. after that the ChilLoadedListener is called and the tree is expanded again.
Hope this will help or at least help you think about your problem ;-)
EDIT :
我现在正在做的项目中也遇到了同样的问题。
我使用 TreeWillExpandListener 来确定何时必须加载我的树。 (延迟加载)
当树展开时,我捕获了该节点并在线程中加载了它的子节点,因为我必须从服务器输出中解析节点。
您面临的问题是树在您的孩子加载之前扩展。所以你必须抛出一个ExpandVetoException或类似的东西并等待你的孩子被加载。然后扩展你的树。在这种情况下,一切都会显示正确。
希望能解决你的问题。
展开->停止展开->加载children->添加子项->现在展开树 ->查看您的节点
编辑:
如果您使用 swing,则最好使用 SwingWorker。对我来说效果更好。
I've had the same problems in the project I am working on right now.
I use an
TreeWillExpandListener
to determine when my tree has to be loaded. (LazyLoading)When the tree expanded I catched the node an loaded it's children inside a thread, because i had to parse the nodes from a server output.
The problem you are facing is that the tree expands before your children are loaded. so you have to throw a
ExpandVetoException
or something like that and wait till your children are loaded. then expand your tree. in this case everything will show right.Hope that will hope your problem.
Exapand-> Stop expand-> loadchildren-> addChildren -> now expand tree -> see your nodes
EDIT :
If you work with swing, you better use SwingWorker. Works better for me.
尝试将
invokeAndWait
替换为invokeLater
。Try replacing
invokeAndWait
withinvokeLater
.