web-dev-qa-db-fra.com

Ajouter et supprimer des nœuds d'un JTree

J'ai un JTree très basique. Comme je suis en Rush, je préfère ne pas utiliser TreeModel si ce n'est pas nécessaire. J'ai écrit un SSCCE pour exposer le problème:

Parfois, j'ajoute un nœud. D'autres fois, je les supprime. Lorsque je pousse Add, un nœud est correctement ajouté. Lorsque je pousse Remove, il est censé supprimer le nœud, mais ce n'est pas le cas. De plus, si j'essaie d'ajouter plusieurs nœuds, l'arborescence ne reste qu'avec le premier nœud que j'ai ajouté.

J'ai écrit une méthode de mise à jour pour le JTree, où j'efface d'abord tous les nœuds suspendus au nœud racine, puis je regarde quels nœuds et sous-nœuds je dois créer.

Qu'est-ce que je fais mal ici, à part ne pas utiliser un TreeModel pour opérer dans l'arborescence?

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<String> graphicIDS;
    private ArrayList<String> graphicInfo;

    public static void main (String [ ] args){
        new TreeTest();
    }

    public TreeTest() {
        graphicIDS = new ArrayList<String>();
        numberOfNodes = 0;
        graphicInfo = new ArrayList<String>();
        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++;
        }
    }
}
20
Roman Rdgz

Je ne sais pas pourquoi vous supprimez et recréez tous les nœuds.

La mise à jour doit toujours être effectuée via le modèle. Vous avez deux choix:

Mettez à jour le modèle directement:

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

Mettez à jour les nœuds d'arborescence, puis notifiez le modèle:

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

Il en va de même pour la suppression des nœuds.

Le DefaultTreeModel a une removeNodeFromParent(...) qui mettra à jour le modèle directement.

Ou vous pouvez utiliser la méthode remove (...) de la classe DefaultMutableTreeNode. Dans ce cas, vous devrez effectuer le rechargement ().

49
camickr