import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;

class SwingTreeFrame extends JFrame {
    public SwingTreeFrame() {
        final int width = 300, height = 300;
        setSize(width,height);
        Container contents = getContentPane();

        setupBookTree();
        setupInputLine();
        JPanel treePanel = new JPanel();
        treePanel.setLayout(new BorderLayout());
        treePanel.add(getBook(),"Center");
        treePanel.add(getInputLine(),"South");
        contents.add(treePanel,"Center");

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(new QuitJButton());
        contents.add(buttonPanel,"South");
    }

    protected void setupBookTree(){
        final DefaultMutableTreeNode root = new DefaultMutableTreeNode("Book");
        // The first string in each row is the chapter title; the remaining
        // strings are some of the section headings.
        final String[][] contents = {
            {"Bits, Bytes and Java",
               "The Challenge","A Simple Model of a Computer",
               "Bits and Bytes","The Central Processing Unit",
            },
            {"Common Program Components",
               "Getting Past the Compiler","Fundamental Language Elements",
               "Compiling and Running Simple Programs",
            },
            {"Creating and Using Objects",
               "Why So Much for So Little?",
               "What are Object-Oriented Languages?",
               "Modeling the Operation of a Port", "...",
            },
            {"Defining Classes",
               "Usage of the Main Method's Class",
               "Object State and Complexity",
               "The Outline of a Class Definition",
               "The SimpleSwitch Class",
               "Encapsulation", "...",
            },
        };
        final int numChapters = contents.length;
        for(int i = 0; i < numChapters; i++){
            DefaultMutableTreeNode chapterNode =
                                new DefaultMutableTreeNode(contents[i][0]);
            final int numSections = contents[i].length;
            for(int j = 1; j < numSections; j++){
                chapterNode.add(new DefaultMutableTreeNode(contents[i][j]));
            }
            root.add(chapterNode);
        }
        DefaultTreeModel model = new DefaultTreeModel(root);
        getBook().setModel(model);
    }

        // Add a listener to the input line.
        // This will add its text to the tree when Enter is pressed.
    protected void setupInputLine(){
        final JTextField line = getInputLine();
        line.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                String text = line.getText();
                if(!text.equals("")){
                    addNode(text);
                    // Clear the line.
                    line.setText("");
                }
            }
        });
    }

        // Find the currently selected node and add text as a child.
    protected void addNode(String text){
        // Add the text as a new node.
        TreePath path = getBook().getSelectionPath();
        if(path != null){
            Object o = path.getLastPathComponent();
            if(o instanceof DefaultMutableTreeNode){
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) o;
                node.add(new DefaultMutableTreeNode(text));
                DefaultTreeModel model =
                        (DefaultTreeModel)getBook().getModel();
                // Tell the tree to redisplay the modified node.
                model.reload(node);
            }
        }
    }

    protected JTree getBook(){
        return book;
    }

    protected JTextField getInputLine(){
        return inputLine;
    }

    // Maintain the book structure in a tree.
    private final JTree book = new JTree();
    // Allow nodes to be added to the book-tree.
    private final JTextField inputLine = new JTextField();
}
