java - 如何从 Thread 对象重新绘制 jTree?

标签 java multithreading swing jtree

我正在使用 jTree 结构来显示用户当前正在使用的项目的结构。当然,用户可以打开另一个项目,然后软件就会显示新项目的结构。我正在使用 DefaultTreeModel 添加/删除节点,并更新 jTree 结构。由于此任务可能需要几秒钟才能完成,因此它是在一个新的 Thread 中实现的。这是代码:

class DrawTreeThread extends Thread {
    @Override
    public void run() {
        System.out.println("drawing the tree");
        model = (DefaultTreeModel) jTree1.getModel();
        Fichier obs,
                open,
                opens = new Fichier(Batiment.data.getAbsolutePath() + "\\Open"), 
                obss = new Fichier(Batiment.data.getAbsolutePath() + "\\Obs"), 
                rooms = new Fichier(Batiment.data.getAbsolutePath() + "\\Rooms");
        Fichier bd = new Fichier(Batiment.data.getAbsolutePath() + "\\BuildingData" + Fichier.EXT);

        int size = rooms.listFiles().length;
        int nbrEtage = bd.readInt("etage");

        DefaultMutableTreeNode[] roomz = new DefaultMutableTreeNode[size];
        DefaultMutableTreeNode bat = new DefaultMutableTreeNode(Batiment.data.getAbsoluteName());
        DefaultMutableTreeNode[] obstacles = new DefaultMutableTreeNode[size];
        DefaultMutableTreeNode[] ouvertures = new DefaultMutableTreeNode[size];
        DefaultMutableTreeNode[] etages = new DefaultMutableTreeNode[nbrEtage];
        jTree1 = new JTree(bat);

        for (int etageCounter = 0; etageCounter < nbrEtage; etageCounter++) {
            String name = "RDC";
            if (etageCounter != 0) {
                name += " + " + etageCounter;
            }
            etages[etageCounter] = new DefaultMutableTreeNode(name);
            bat.add(etages[etageCounter]);
            model.insertNodeInto(etages[etageCounter], bat, 0);
        }


        for (int i = 0; i < size; i++) {
            roomz[i] = new DefaultMutableTreeNode(rooms.listFiles()[i].getAbsoluteName());
            obs = new Fichier(obss.getAbsolutePath() + "\\" + rooms.listFiles()[i].getAbsoluteName());
            open = new Fichier(opens.getAbsolutePath() + "\\" + rooms.listFiles()[i].getAbsoluteName());
            etages[rooms.listFiles()[i].readInt("etage")].add(roomz[i]);
            obstacles[i] = new DefaultMutableTreeNode("Obstacles (" + obs.listFiles().length + ")");
            ouvertures[i] = new DefaultMutableTreeNode("Ouvertures (" + open.listFiles().length + ")");
            roomz[i].add(obstacles[i]);
            roomz[i].add(ouvertures[i]);

            DefaultMutableTreeNode[] Obs = new DefaultMutableTreeNode[obs.listFiles().length];
            for (int j = 0; j < obs.listFiles().length; j++) {
                Obs[j] = new DefaultMutableTreeNode(obs.listFiles()[j].getAbsoluteName());
                obstacles[i].add(Obs[j]);
            }

            DefaultMutableTreeNode[] Open = new DefaultMutableTreeNode[open.listFiles().length];
            for (int j = 0; j < open.listFiles().length; j++) {
                Open[j] = new DefaultMutableTreeNode(open.listFiles()[j].getAbsoluteName());
                ouvertures[i].add(Open[j]);
            }
        }

        model.nodeStructureChanged(bat);
        model.reload();

        jTree1.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        jTree1.expandRow(0);
        System.out.println("drawing the tree with success");

    }
}

new DrawTreeThread().start() 从按钮 ActionListner() 调用,但没有任何反应。怎么了?

最佳答案

jTree1 = new JTree(bat); 

这什么都不做。您所做的只是在内存中创建一个新的 JTree 对象。您实际上还没有将树添加到 GUI。

无需创建新树。相反,您可以创建一个新的 TreeModel 并使用以下方法更新现有的树:

tree.setModel(...);

此外,当您调用上述方法时,您应该将其包装在 SwingUtilities.invokeLater() 中,以便 GUI 在 EDT 上更新。

关于java - 如何从 Thread 对象重新绘制 jTree?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7198691/

相关文章:

java - Tomcat 因大量请求而挂起

javascript - Node.js 中的多线程?

java - ReentrantReadWriteLock(java)-在读取锁内嵌套写入锁

Java Swing JOptionPane 按钮选项

java - Java中共享变量的顺序使用

Java Swing UI 替换

java - Android - 按住按钮时重复功能

java - 如何在行覆盖中包含私有(private)构造函数?

java - 使用自定义容器作为 TestContainer 的数据库

c++ - 从 std::scoped_lock 抛出的异常