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
19
「急いで」いると、あなたの速度が遅くなっている可能性があります。 @camickrが示唆しているように、このモデルを使用することは適切なアプローチです。 +1、btw、完全な例です。
追加された 著者 trashgod,
急いでいるかどうかにかかわらず、ノードを足元で変更した場合、モデルに通知する必要があります 。周りにはありません。 @camickrショー、あなたのやり方、私のコメントで飾った:-)
追加された 著者 kleopatra,

1 答え

私はなぜあなたがすべてのノードを削除して再作成しているのかわかりません。

更新は常にモデルを介して行う必要があります。あなたにはいくつかの選択肢があります:

モデルを直接更新する:

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()を実行する必要があります。

46
追加された
子の値を削除するのはどうですか?
追加された 著者 Nitesh Verma,
ありがとう、私はそれが本当にあったより複雑になっていた
追加された 著者 Roman Rdgz,
ありがとう。私はもっ​​とJTreeで遊ぶ必要があります:)
追加された 著者 camickr,
+1 - リロードを受け取ります;-)モデルにはnodesLhereInsertedRremoved/Changedがありますが、実際の名前の後にリスナーに通知するために、eactの名前を釘付けにしてはいけません。リロードは最後の手段です、f.i.ツリーのいくつかの深さで複雑な変更を行った後
追加された 著者 kleopatra,
明確にするために;ノードを削除するときに nodeChanged()メソッドがバグの原因となるため、 reload()はうまく動作します。これは、 nodeChanged()がツリーを折りたたむのではなく、 reload()が行うためです。
追加された 著者 glend,