Java 设置新JTree模型后刷新JTree

Java 设置新JTree模型后刷新JTree,java,user-interface,swing,jtree,Java,User Interface,Swing,Jtree,我正在尝试使用动态JTree组件。 在根节点下,我有四个节点,其中一个(“操作”)可以有0到多个子节点。这由用户通过在单独窗口中的可编辑列表进行设置,该窗口根据用户请求打开。编辑此列表后,用户点击“保存”按钮,然后神奇的事情就会发生。编辑后的列表被发送到服务器(实际上在同一台机器上,所以不会花太长时间),带有列表的窗口被关闭,但就在主窗口(带有jtree)被告知刷新自己之前,我可以看到它执行日志输出中告诉的操作,但更改不会显示在屏幕上 我使用的是DefaultTreeModel,在开始(第一次打

我正在尝试使用动态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的方法如下所示(非常混乱):

这是非常混乱的,因为我试图把我在论坛上找到的问题的所有可能的解决方案都放在那里, 我还尝试了我自己的treemodel实现,它将调用fireTreeStructureChanged(…),但它也没有改变

我可能还应该补充一点,我正在使用netbeansguibuilder构建我的GUI,尽管我不知道这是否与此有关

如果能在这方面得到任何帮助,我将不胜感激

溴 卢卡

编辑 我还试着把它放在另一个类似的线程中:

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();
}

但它也没有帮助。

在我看来,自己的
TreeModel
实现是一个很好的方法。但是我知道用正确的数据创建一个
TreeModelEvent
并不是那么简单


我建议您使用TreeModel实现更新您的问题,以便我们能够找到问题所在。

原则上,它应该以这种方式工作(当您设置新模型时,树会自动重新加载)。(这不是最有效的方法,最好让模型在更改时发送适当的事件。)

如果这不起作用,请确保您正在AWT事件分派线程(使用
EventQueue.invokeLater
(或
SwingUtilities.invokeLater
,两者相同)中调用
setModel
方法。例如,我认为您不需要所有
revalidate()
repaint()
等调用(和
updateUI
只有在更改外观配置时才能执行)

是您需要的唯一代码行


如果它不起作用,那就意味着树变量不包含对添加到GUI中的树的引用。也许你有一个类变量和一个同名的局部变量。

好吧,也许你自己的树模型实现很好,当你想对树做任何花哨的事情时,我只是交换整个模型。实际上我一直在ady删除了我自己模型的代码,但它非常简单,看起来像这样:MyTreeModel类扩展了DefaultTreeModel{public MyTableModel(DefaultMutableTreeNode dmtn){super(dmtn);}public void refresh(){this.fireTreeStructureChanged(pa,ra,me,ters);}它按照您在AWT事件分派线程中所描述的方式运行,正如我所说的,它是由用户结束列表编辑触发的,通过点击一个按钮private void jButton2MouseClicked(java.AWT.Event.MouseEvent evt){task.setData((MyDefaultTableModel)jTable1.getModel()).getDataVector(),dataName);parent.updateTree();parent.updateStatus();this.dispose();}其中parent是我的面板对象,在我的第一篇文章中粘贴了方法。它是同一个变量,我仔细检查了它。问题可能是由netbeans gui builder执行的绑定引起的?binding=org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE,this,org.jdesktop.beansbinding.ELProperty.create(“${dataStructure}”)、taskDataTree,org.jdesktop.beansbinding.BeanProperty.create(“model”);bindingGroup.addBinding(binding);也许有一种方法可以使用此绑定更新我的jtree?它使用我的方法检索数据以初始创建jtree,然后工作正常,您知道有什么方法调用此绑定以便再次检索数据吗?我对Netbeans绑定一无所知。您为什么不使用Netbeans绑定代码来尝试它呢。
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();
}
tree.setModel( anotherModel );