Re:JTree - inserção de um nodo

4 respostas
ViniGodoy

Você está usando o defaulTreeModel, ou um model que você mesmo fez?

Normalmente problemas desse tipo acontecem quando o model esquece de disparar o evento fireTreeNodesChanged. É esse evento que “avisa” a árvore que ela deve ser atualizada.

Esse evento tem uns parâmetros meio chatos, para alterar somente uma folha, coloque os seguintes métodos no seu model e dispare-os quando você terminar de inserir o nó:

protected void fireLastPathComponentChanged(Object... path) {
    fireTreeNodesChanged(this, new TreePath(path).getPath(), new int[] {},
            new Object[] {});
}

protected void fireLastPathComponentInserted(Object... path) {
    TreePath treePath = new TreePath(path);
    Object parent = treePath.getParentPath().getLastPathComponent();
    Object leaf = treePath.getLastPathComponent();

    int index = getIndexOfChild(parent, leaf);

    fireTreeNodesInserted(this, treePath.getParentPath().getPath(),
            new int[] {index}, new Object[] {leaf});
}

protected void fireLastPathComponentRemoved(Object... path) {
    TreePath treePath = new TreePath(path);
    Object parent = treePath.getParentPath().getLastPathComponent();
    Object leaf = treePath.getLastPathComponent();

    int index = getIndexOfChild(parent, leaf);

    fireTreeNodesRemoved(this, treePath.getParentPath().getPath(),
            new int[] {index}, new Object[] {leaf});
}

A classe em anexo, AbstractTreeModel, contém a implementação completa de um TreeModel que usamos quando queremos implementar os nossos. É muito prática! Dê uma olhada.

Se você está utilizando o DefaultTableModel, procure um método parecido com um desses acima e dispare-o assim que você atualiza seu nó.

Para mais informações tem sempre o site da Sun:
http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html

4 Respostas

felixcomputer

Olá lance, estava tendo exatamente o mesmo problema que vc, entretanto consegui fazer funcionar com essa classe:

import java.awt.GridLayout;
import java.awt.Toolkit;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;

public class DynamicTree extends JPanel {
   protected DefaultMutableTreeNode rootNode;
   protected DefaultTreeModel treeModel;
   protected JTree tree;
   private Toolkit toolkit = Toolkit.getDefaultToolkit();

   public DynamicTree() {
       super(new GridLayout(1,0));
       
       rootNode = new DefaultMutableTreeNode("Root Node");
       treeModel = new DefaultTreeModel(rootNode);
       treeModel.addTreeModelListener(new MyTreeModelListener());

       tree = new JTree(treeModel);
       tree.setEditable(true);
       tree.getSelectionModel().setSelectionMode
               (TreeSelectionModel.SINGLE_TREE_SELECTION);
       tree.setShowsRootHandles(true);

       JScrollPane scrollPane = new JScrollPane(tree);
       add(scrollPane);
   }

   /** Remove all nodes except the root node. */
   public void clear() {
       rootNode.removeAllChildren();
       treeModel.reload();
   }

   /** Remove the currently selected node. */
   public void removeCurrentNode() {
       TreePath currentSelection = tree.getSelectionPath();
       if (currentSelection != null) {
           DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
                        (currentSelection.getLastPathComponent());
           MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
           if (parent != null) {
               treeModel.removeNodeFromParent(currentNode);
               return;
           }
       } 

       // Either there was no selection, or the root was selected.
       toolkit.beep();
   }

   /** Add child to the currently selected node. */
   public DefaultMutableTreeNode addObject(Object child) {
       DefaultMutableTreeNode parentNode = null;
       TreePath parentPath = tree.getSelectionPath();

       if (parentPath == null) {
           parentNode = rootNode;
       } else {
           parentNode = (DefaultMutableTreeNode)
                        (parentPath.getLastPathComponent());
       }

       return addObject(parentNode, child, true);
   }

   public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                           Object child) {
       return addObject(parent, child, false);
   }

   public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                           Object child, 
                                           boolean shouldBeVisible) {
       DefaultMutableTreeNode childNode = 
               new DefaultMutableTreeNode(child);

       if (parent == null) {
           parent = rootNode;
       }

       treeModel.insertNodeInto(childNode, parent, 
                                parent.getChildCount());

       //Make sure the user can see the lovely new node.
       if (shouldBeVisible) {
           tree.scrollPathToVisible(new TreePath(childNode.getPath()));
       }
       return childNode;
   }

   class MyTreeModelListener implements TreeModelListener {
       public void treeNodesChanged(TreeModelEvent e) {
           DefaultMutableTreeNode node;
           node = (DefaultMutableTreeNode)
                    (e.getTreePath().getLastPathComponent());

           /*
            * If the event lists children, then the changed
            * node is the child of the node we've already
            * gotten.  Otherwise, the changed node and the
            * specified node are the same.
            */
           try {
               int index = e.getChildIndices()[0];
               node = (DefaultMutableTreeNode)
                      (node.getChildAt(index));
           } catch (NullPointerException exc) {}

           System.out.println("The user has finished editing the node.");
           System.out.println("New value: " + node.getUserObject());
       }
       public void treeNodesInserted(TreeModelEvent e) {
       }
       public void treeNodesRemoved(TreeModelEvent e) {
       }
       public void treeStructureChanged(TreeModelEvent e) {
       }
   }
}

Uma Classe Demo

/*
 * This code is based on an example provided by Richard Stanford, 
 * a tutorial reader.
 */

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.tree.DefaultMutableTreeNode;

public class DynamicTreeDemo extends JPanel 
                             implements ActionListener {
    private int newNodeSuffix = 1;
    private static String ADD_COMMAND = "add";
    private static String REMOVE_COMMAND = "remove";
    private static String CLEAR_COMMAND = "clear";
    
    private DynamicTree treePanel;

    public DynamicTreeDemo() {
        super(new BorderLayout());
        
        //Create the components.
        treePanel = new DynamicTree();
        populateTree(treePanel);

        JButton addButton = new JButton("Add");
        addButton.setActionCommand(ADD_COMMAND);
        addButton.addActionListener(this);
        
        JButton removeButton = new JButton("Remove");
        removeButton.setActionCommand(REMOVE_COMMAND);
        removeButton.addActionListener(this);
        
        JButton clearButton = new JButton("Clear");
        clearButton.setActionCommand(CLEAR_COMMAND);
        clearButton.addActionListener(this);

        //Lay everything out.
        treePanel.setPreferredSize(new Dimension(300, 150));
        add(treePanel, BorderLayout.CENTER);

        JPanel panel = new JPanel(new GridLayout(0,1));
        panel.add(addButton);
        panel.add(removeButton);
        panel.add(clearButton);
        add(panel, BorderLayout.LINE_END);
    }

    public void populateTree(DynamicTree treePanel) {
        String p1Name = new String("Parent 1");
        String p2Name = new String("Parent 2");
        String c1Name = new String("Child 1");
        String c2Name = new String("Child 2");

        DefaultMutableTreeNode p1, p2;

        p1 = treePanel.addObject(null, p1Name);
        p2 = treePanel.addObject(null, p2Name);

        treePanel.addObject(p1, c1Name);
        treePanel.addObject(p1, c2Name);

        treePanel.addObject(p2, c1Name);
        treePanel.addObject(p2, c2Name);
    }
    
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        
        if (ADD_COMMAND.equals(command)) {
            //Add button clicked
            treePanel.addObject("New Node " + newNodeSuffix++);
        } else if (REMOVE_COMMAND.equals(command)) {
            //Remove button clicked
            treePanel.removeCurrentNode();
        } else if (CLEAR_COMMAND.equals(command)) {
            //Clear button clicked.
            treePanel.clear();
        }
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("DynamicTreeDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        DynamicTreeDemo newContentPane = new DynamicTreeDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

Contudo ela requer o Java 6
flws

root_

Ótimo exemplo felixcomputer, VLW mesmo… xD

Matheus_Prado

alguem sabe mi dizer pra que serve e como usar esse métodos,
to precisando de ajuda
obrigado

public void treeNodesChanged(TreeModelEvent e) {   
       }   
       public void treeNodesInserted(TreeModelEvent e) {   
       }   
       public void treeNodesRemoved(TreeModelEvent e) {   
       }   
       public void treeStructureChanged(TreeModelEvent e) {   
       }

obrigadoo

L

Olá
tenho uma JTree. Quando inicializo a aplicção, populo-a com 3 níveis (root, pais e folhas), isto está funcionando. Porém quando eu tento inserir mais um nodo no último nível, as folhas são inseridas para todos, porém só são visíveis para os nodos que não foram expandidos ainda.
Por exemplo
root
*Pai1
-Folha1
*Pai2
-Folha2

Está é a estrutura da árvore.Se eu não expandir nenhum nodo, os novos valores são inseridos e mostrados perfeitamente.
Se eu expando algum dos nodos, este nodo não mostra o valor inserido depois.
Alguém sabe como “atualizar” a árvore? Eu tentei usar repaint e etc, mas não funciona.;.

Obrigado,
Oscar

Criado 10 de janeiro de 2007
Ultima resposta 9 de jan. de 2007
Respostas 4
Participantes 5