【问题标题】:JTree: won't redisplay new modelJTree:不会重新显示新模型
【发布时间】:2012-07-19 03:02:54
【问题描述】:

当我启动我的 Java swing 应用程序时,我将一个 XML 文件读入 DefaultTreeModel,使用该模型创建一个新的 JTree,将 jtree 添加到一个 JScrollPane,然后生活就是美好的。一切正常:

// Program initialization:
jarFilesDB = new JarFilesDB ();
jarFilesDB.load(JarFilesDB.JAR_DB_FILENAME);
jtree = new JTree(jarFilesDB.getRootNode ());
JScrollPane scrollPane = new JScrollPane (jtree);
contentPane.add(scrollPane, BorderLayout.CENTER);

稍后,我可能想创建一个 XML 文件,并完全重建我的模型。当我这样做时,我无法让 jtree 重新显示新模型。要么我得到一个空白窗格,要么仍然显示旧模型:

// Completely regenerate XML file and Model
jarFilesDB.mkXmlFile (sPath);                // Generate new XML file
jarFilesDB.load(JarFilesDB.JAR_DB_FILENAME); // Generate new Model

根据 Andrew Thompson 的要求,我写了一个“简短(尽可能)、独立、正确(不是!否则我不会问这个问题)示例):

package com.rgb;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTree;
import javax.swing.JScrollPane;
import javax.swing.tree.*;

public class FrmMain extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    FrmMain frame = new FrmMain();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public FrmMain() {
        setTitle("HelloJTree3");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JButton btnNewButton = new JButton("Click Me");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                doClick ();
            }
        });
        contentPane.add(btnNewButton, BorderLayout.NORTH);
        jarFilesDB = new JarFilesDB ();
        jarFilesDB.load(isAlpha);
        isAlpha = !isAlpha;
        jtree = new JTree(jarFilesDB.getRootNode ());
        JScrollPane scrollPane = new JScrollPane (jtree);
        contentPane.add(scrollPane, BorderLayout.CENTER);   
    }

    private void doClick () {
        jarFilesDB.load(isAlpha);
        isAlpha = !isAlpha;
    }

    private JarFilesDB jarFilesDB;
    private JTree jtree;
    private boolean isAlpha = false;
}

class JarFilesDB extends DefaultTreeModel {

    public JarFilesDB () {
        super (null);
    }

    public void load (boolean isAlpha) {
        if (rootNode == null)
            rootNode =  new DefaultMutableTreeNode("root");
        else
            rootNode.removeAllChildren ();

        String[] values;
        if (isAlpha)
            values = new String[] {"A", "A1", "A2", "B", "B1", "B2"};
        else
            values = new String[] {"10", "11", "12", "20", "21", "22"};

        DefaultMutableTreeNode childNode = new DefaultMutableTreeNode (values[0]);
        DefaultMutableTreeNode leafNode = new DefaultMutableTreeNode (values[1]);
        childNode.add(leafNode);
        leafNode = new DefaultMutableTreeNode (values[2]);
        childNode.add(leafNode);
        rootNode.add(childNode);

        childNode = new DefaultMutableTreeNode (values[3]);
        leafNode = new DefaultMutableTreeNode (values[4]);
        childNode.add(leafNode);
        leafNode = new DefaultMutableTreeNode (values[5]);
        childNode.add(leafNode);
        rootNode.add(childNode);
    }

    public TreeNode getRootNode () {
        return rootNode;
    }

    private DefaultMutableTreeNode rootNode = null;

}

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 初始化树时为什么不用jtree.setModel(jarFilesDB);
  • @Max - jarFilesDB 类继承自 DefaultTreeModel。我最初不需要“setModel()”,因为我只是使用模型的根节点作为 jtree 的构造函数。您删除的响应是正确的:我不应该需要 removeAll() 或 setModel()。任何建议都将不胜感激:) 提前谢谢...
  • @paulsm4 ,在上面的代码中,在初始化过程中,树用提供的根节点创建了自己的DefaulTreeModel。稍后,在更新期间,您将其提供给您的实现。只是为了确保您的模型得到正确实现,请在初始化树时使用它并查看您得到正确的结果。然后用更新测试它。当然,你也可以反之亦然:)
  • @Andrew Thompson - 我添加了一个“SSCCE”来重现该问题。 jtree 只显示第一个模型(“数字”),无论我更改多少次。我确定问题很简单 - 请让我知道您的想法!

标签: java swing jtree


【解决方案1】:

add() 方法不会触发更新。最好使用insertNodeInto。要修复,请添加以下内容:

nodeStructureChanged(rootNode);

load() 方法的末尾。

并使用它来初始化树:

jtree = new JTree(jarFilesDB);

这是更新后的 SSCCE,不知道 rootNode 的意图是什么,所以我不管它:

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTree;
import javax.swing.JScrollPane;
import javax.swing.tree.*;

public class FrmMain extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    FrmMain frame = new FrmMain();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public FrmMain() {
        setTitle("HelloJTree3");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JButton btnNewButton = new JButton("Click Me");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                doClick ();
            }
        });
        contentPane.add(btnNewButton, BorderLayout.NORTH);
        jarFilesDB = new JarFilesDB ();
        jarFilesDB.load(isAlpha);
        isAlpha = !isAlpha;
        //jtree = new JTree(jarFilesDB.getRootNode ());
        jtree = new JTree(jarFilesDB);
        JScrollPane scrollPane = new JScrollPane (jtree);
        contentPane.add(scrollPane, BorderLayout.CENTER); 
    }

    private void doClick () {
        jarFilesDB.load(isAlpha);
        isAlpha = !isAlpha;
    }

    private JarFilesDB jarFilesDB;
    private JTree jtree;
    private boolean isAlpha = false;
}

class JarFilesDB extends DefaultTreeModel {

    public JarFilesDB () {
        super (new DefaultMutableTreeNode("root"));
        rootNode = (DefaultMutableTreeNode) getRoot(); 
    }

    public void load (boolean isAlpha) {
        rootNode.removeAllChildren ();

        String[] values;
        if (isAlpha)
            values = new String[] {"A", "A1", "A2", "B", "B1", "B2"};
        else
            values = new String[] {"10", "11", "12", "20", "21", "22"};

        DefaultMutableTreeNode childNode = new DefaultMutableTreeNode (values[0]);
        DefaultMutableTreeNode leafNode = new DefaultMutableTreeNode (values[1]);
        childNode.add(leafNode);
        leafNode = new DefaultMutableTreeNode (values[2]);
        childNode.add(leafNode);

        rootNode.add(childNode);

        childNode = new DefaultMutableTreeNode (values[3]);
        leafNode = new DefaultMutableTreeNode (values[4]);
        childNode.add(leafNode);
        leafNode = new DefaultMutableTreeNode (values[5]);
        childNode.add(leafNode);
        rootNode.add(childNode);

        nodeStructureChanged(rootNode);
    }

    public TreeNode getRootNode () {
        return rootNode;
    }

    private DefaultMutableTreeNode rootNode = null;

}

【讨论】:

    【解决方案2】:

    或者,您可以使用JTree.updateUI()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 2012-06-06
      • 2020-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多