Java Usage of jTree and jScrollPane #5

We extend the original TreeTest3 by adding the ability to add new nodes.
In general, what is shown in blue is stuff generated by the IDE (not completely, however), and what is shown in black is my typing (I hope you know what I mean).
I will annotate the text in color comments which should be self evident as to whether they are code or comments.
 

/*
 * TreeTest5.java
 *
 * Created on August 21, 2003, 2:49 PM
 */

/**
 *
 * @author  Administrator
 */


import java.util.Vector;//to use vectors
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;// needed to get TreeModelListener
//don't forget to set editable true in IDE to get TreeTest3 behavior
import javax.swing.JOptionPane;//added to get interogative dialog for new nodes


public class TreeTest5 extends javax.swing.JFrame implements WindowListener, java.awt.event.ActionListener{
    
    /** Creates new form TreeTest5 */
    public TreeTest5() {
        initComponents();


This is a new way of adding nodes and leaves to a tree, which, we are
warned, is not serializeable, which means that when we pass past 1.4, there
is no assurance that this will work.
But, untill then, here it is:

        Vector Vect = new Vector();
        Vector rightVect = new Vector();
        
        rootNode = new DefaultMutableTreeNode("Root");

        Vect.add("7");
        Vect.add("8");
        
        DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("*");

        JTree.DynamicUtilTreeNode.createChildren(node1,Vect);//this is the hard one
        rootNode.add(node1);

That's the end of the new method

        treeModel = new DefaultTreeModel(rootNode);

        jTree1.setModel(treeModel);
        
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        jScrollPane1 = new javax.swing.JScrollPane();
        jTree1 = new javax.swing.JTree();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();

        addWindowListener(this);

        jTree1.setEditable(true);
        jScrollPane1.setViewportView(jTree1);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jButton1.setText("Add a Node");
        jButton1.setName("AddNode");
        jButton1.addActionListener(this);

        getContentPane().add(jButton1, java.awt.BorderLayout.NORTH);

        jButton2.setText("Delete a Node");
        jButton2.setName("RemoveNode");
        jButton2.addActionListener(this);

        getContentPane().add(jButton2, java.awt.BorderLayout.SOUTH);

        pack();
    }

    // Code for dispatching events from components to event handlers.

    public void actionPerformed(java.awt.event.ActionEvent evt) {
        if (evt.getSource() == jButton1) {
            TreeTest5.this.jButton1ActionPerformed(evt);
        }
        else if (evt.getSource() == jButton2) {
            TreeTest5.this.jButton2ActionPerformed(evt);
        }
    }

    public void windowActivated(java.awt.event.WindowEvent evt) {
    }

    public void windowClosed(java.awt.event.WindowEvent evt) {
    }

    public void windowClosing(java.awt.event.WindowEvent evt) {
        if (evt.getSource() == TreeTest5.this) {
            TreeTest5.this.exitForm(evt);
        }
    }

    public void windowDeactivated(java.awt.event.WindowEvent evt) {
    }

    public void windowDeiconified(java.awt.event.WindowEvent evt) {
    }

    public void windowIconified(java.awt.event.WindowEvent evt) {
    }

    public void windowOpened(java.awt.event.WindowEvent evt) {
    }//GEN-END:initComponents
    
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        // Add your handling code here:

        //REMOVE A NODE
        int n = JOptionPane.showConfirmDialog( this, "Are You Sure?",
        "Question", JOptionPane.YES_NO_OPTION,
        JOptionPane.QUESTION_MESSAGE, null );
        if (n == JOptionPane.YES_OPTION) {
            removeCurrentNode();
        } else if (n == JOptionPane.NO_OPTION) {
            return;
        } else {
            return;
        }

        
    }//GEN-LAST:event_jButton2ActionPerformed
    
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // Add your handling code here:

        String s = (String)JOptionPane.showInputDialog(this,"Enter a Node value");
        addObject(s);

    }//GEN-LAST:event_jButton1ActionPerformed
    
    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
        System.exit(0);
    }//GEN-LAST:event_exitForm
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new TreeTest5().show();
    }
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTree jTree1;
    // End of variables declaration//GEN-END:variables


These declarations had to be made here, publically, to use them in 
the context of the routines shown below

    DefaultMutableTreeNode rootNode;
    DefaultMutableTreeNode childNode, grandchildNode;
    DefaultTreeModel treeModel;
    
    
    class MyTreeModelListener implements TreeModelListener{
        //subroutine inserted by IDE:
        public void treeNodesChanged(TreeModelEvent e){
            /*text from java.sun.com/docs.tutorial/uiswing/components/tree.html
             * hand copied directly
             */
            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("The New Value is "+node.getUserObject());
        }
        
        
        
        
        public void treeNodesInserted(TreeModelEvent e) {
            System.out.println("treeNodesInserted");
        }
        
        public void treeNodesRemoved(TreeModelEvent e) {
            System.out.println("treeNodesRemoved");
        }
        
        public void treeStructureChanged(TreeModelEvent e) {
            System.out.println("treeStructureChanged");
        }
    }
    
/*this code is from the sun documentation, and Richard Stanford's example
 *of how to insert nodes
 */

I find the following quite confusing, since there are three separate
functions created, each called addObject. Their calling sequences are different,
which appears to be the trick in Java, but it takes from getting used to for
and old FORTRAN programmer.

    
    public DefaultMutableTreeNode addObject(Object child){
        DefaultMutableTreeNode parentNode = null;
        TreePath parentPath = jTree1.getSelectionPath();
        if(parentPath == null){
            //there's no selection, default to the root node
            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 loverly new node.
        if (shouldBeVisible){
            jTree1.scrollPathToVisible(new TreePath(childNode.getPath()));
        }
        return childNode;
    }

Here starts the new node removing subroutines

    
    public void clear(){
        //remove all nodes except for rootNode
        rootNode.removeAllChildren();
        treeModel.reload();
    }
    
    public void removeCurrentNode(){
        TreePath currentSelection = jTree1.getSelectionPath();
        if(currentSelection != null){
            DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
            (currentSelection.getLastPathComponent());
            MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
            if(parent != null){
                treeModel.removeNodeFromParent(currentNode);
                return;
            }
        }
    }
}

Return to the main book TOC.