从JTree添加和删除节点

我有一个非常基本的JTree 。 因为我匆忙,如果不需要,我宁愿不使用TreeModel 。 我写了一个SSCCE来揭露这个问题:

有时我会添加一个节点。 其他时候我删除它们。 当我按下Add ,正确添加了一个节点。 当我推送Remove ,它应该删除节点,但它不会。 此外,如果我尝试添加多个节点,树只会保留我添加的第一个节点。

我为JTree编写了一个更新方法,首先擦除从根节点挂起的所有节点,然后查看我必须创建的节点和子节点。

除了不使用TreeModel操作树之外,我在这里做错了什么?

 import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; public class TreeTest { private JFrame myFrame; private JTree myTree; private JButton addButton, removeButton; private int numberOfNodes; private DefaultMutableTreeNode rootNode; private ArrayList graphicIDS; private ArrayList graphicInfo; public static void main (String [ ] args){ new TreeTest(); } public TreeTest() { graphicIDS = new ArrayList(); numberOfNodes = 0; graphicInfo = new ArrayList(); graphicInfo.add("Info A"); graphicInfo.add("Info B"); graphicInfo.add("Info C"); graphicInfo.add("Info D"); JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); myFrame = new JFrame("JTree test"); myFrame.setResizable(false); myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.NORTH; c.gridx = 0; c.gridy = 0; c.gridwidth = 2; c.insets = new Insets(5,5,5,5); rootNode = new DefaultMutableTreeNode("Root node"); myTree = new JTree(rootNode); myTree.setPreferredSize(new Dimension(200, 500)); panel.add(myTree, c); c.gridwidth = 1; c.gridy++; removeButton = new JButton("Remove"); removeButton.setEnabled(false); removeButton.addActionListener(new ActionListener (){ @Override public void actionPerformed(ActionEvent e) { System.out.println("Removed curve "+(graphicIDS.size())); graphicIDS.remove(graphicIDS.size()-1); numberOfNodes--; updateMeasurementsTree(); } }); panel.add(removeButton, c); c.gridx++; addButton = new JButton("Add"); addButton.addActionListener(new ActionListener (){ @Override public void actionPerformed(ActionEvent e) { graphicIDS.add("Curve "+(numberOfNodes+1)); System.out.println("Added curve "+(numberOfNodes+1)); numberOfNodes++; updateMeasurementsTree(); } }); panel.add(addButton, c); myFrame.getContentPane().add(panel); myFrame.pack(); myFrame.setVisible(true); } public void updateMeasurementsTree(){ rootNode.removeAllChildren(); for(int i=0; i<numberOfNodes;i++){ String idString = graphicIDS.get(i); DefaultMutableTreeNode idNode = new DefaultMutableTreeNode("Graphic "+idString); rootNode.add(idNode); int randomValue = (int) Math.floor(Math.random()*graphicInfo.size()); String infoString = graphicInfo.get(randomValue); DefaultMutableTreeNode infoNode = new DefaultMutableTreeNode("Info "+infoString); idNode.add(infoNode); } if(numberOfNodes==0) removeButton.setEnabled(false); else{ removeButton.setEnabled(true); expandAll(); } } public void expandAll() { int row = 0; while (row < myTree.getRowCount()) { myTree.expandRow(row); row++; } } } 

我不知道你为什么要删除并重新创建所有节点。

应始终通过模型进行更新。 你有几个选择:

直接更新模型:

 DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); model.insertNodeInto(new DefaultMutableTreeNode("another_child"), root, root.getChildCount()); 

更新树节点,然后通知模型:

 DefaultTreeModel model = (DefaultTreeModel)tree.getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot(); root.add(new DefaultMutableTreeNode("another_child")); model.reload(root); 

这同样适用于删除节点。

DefaultTreeModel有一个removeNodeFromParent(...) ,它将直接更新模型。

或者,您可以使用DefaultMutableTreeNode类的remove(…)方法。 在这种情况下,您需要执行reload()。