我正在尝试使用动态JTree组件。 在根节点下,我有四个节点,其中一个节点(“操作”)可以有0到多个子节点。这是由用户通过可编辑列表在用户请求打开的单独窗口中设置的。编辑此列表后,用户点击“保存”按钮,然后就会发生魔法。编辑列表被发送到服务器(实际上在同一台机器上,所以它不需要很长时间),带有列表的窗口关闭但在此之前主窗口(带有jtree)被告知刷新自己,我可以看到它会执行日志输出中的操作,但更改不会显示在屏幕上。
我正在使用DefaultTreeModel,调用此方法以在开始时(首次打开窗口时)创建模型,并在更改后使用新结构更新新模型。 使用dmtn.getLeafCount()我可以看到服务器中新下载的结构是正确的,在“操作”下有更改的叶子数
public DefaultTreeModel getDataStructure() {
int dataID = task.getData().getId();
LoggerUtility.logger.info("Data ID: " + dataID);
DefaultMutableTreeNode dmtn = Manager.manager.getDataStructure(task.getId());
LoggerUtility.logger.info("DTMN created "+dmtn.getLeafCount());
return new DefaultTreeModel(dmtn);
}
用于刷新jtree的方法看起来像这样(它非常混乱):
public void updateTree(){
taskDataTree.setModel(getDataStructure());
((DefaultTreeModel)taskDataTree.getModel()).reload();
this.revalidate();
this.repaint();
taskDataTree.revalidate();
taskDataTree.repaint();
taskDataTree.updateUI();
taskDataTree.setVisible(false);
taskDataTree.setVisible(true);
jScrollPane2.setViewportView(taskDataTree);
}
这非常混乱,因为我试图在论坛上找到我遇到的问题的所有可能的解决方案, 我也试过了我自己的treemodel实现,它会调用fireTreeStructureChanged(...),但它也没有改变。
我应该补充一点,我正在使用Netbeans GUI Builder来构建我的gui,虽然我不知道它是否与此有关。
我非常感谢你提供任何帮助
BR Lucja
修改!!! 我也试过把它放在另一个这样的线程中:
public void updateTree() {
SwingWorker sw = new SwingWorker() {
@Override
protected Object doInBackground() throws Exception {
taskDataTree.setModel(getDataStructure());
((DefaultTreeModel) taskDataTree.getModel()).reload();
taskDataTree.revalidate();
taskDataTree.repaint();
taskDataTree.updateUI();
taskDataTree.setVisible(false);
taskDataTree.setVisible(true);
jScrollPane2.setViewportView(taskDataTree);
return null;
}
};
sw.execute();
}
但它也没有帮助。
答案 0 :(得分:2)
tree.setModel( anotherModel );
是您需要的唯一代码行。
如果它不起作用则表示树变量不包含对添加到GUI的树的引用。也许你有一个类变量和一个同名的局部变量。
答案 1 :(得分:0)
从我的观点来看,自己的TreeModel
实施是一种很好的方法。但我知道用正确的数据创建TreeModelEvent
并不是那么简单。
我建议您使用TreeModel实现更新您的问题,以便我们可以找到它的问题。
答案 2 :(得分:0)
原则上它应该以这种方式工作(当你设置一个新模型时,树会重新加载它自己)。 (这不是最有效的方法,更好的是让模型在发生变化时发送适当的事件。)
如果这不起作用,请确保在AWT事件调度线程中调用setModel
方法(例如EventQueue.invokeLater
(或SwingUtilities.invokeLater
,这是相同的),例如我认为您不应该需要所有revalidate()
,repaint()
等来电(只有在您更改了外观配置时才能updateUI
)。