3

This applet should take the tree stored in menuTree and follow a menu construction based on it.

currentNode stores the menu the applet is currently on, and each of its children should be displayed as buttons.

Upon clicking a button the applet should take you to a new menu, representing the button clicked.

I'm having trouble getting the buttons to change upon another button being clicked.

I'm not particularly sure that the tree is even properly constructed, as its not particularly easy to test.

Any help would be greatly appreciated.

Thank you.

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

public class Menu extends JApplet implements ActionListener{
    private static final long serialVersionUID = 2142470002L;
    private JTree menuTree;
    private DefaultMutableTreeNode currentNode;
    private JPanel buttonPanel;

    public void init(){
        this.setSize(700, 550);
        buttonPanel=new JPanel();
        buttonPanel.setSize(300, 500);
        this.add(buttonPanel);

        /**
         * will make node out of the first entry in the array, then make nodes out of subsequent entries
         * and make them child nodes of the first one. The process is  repeated recursively for entries that are arrays.
         * this idea of tree declaration as well as the code from the method was lovingly
         * stolen from: http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-JTree.html
         */
        Object [] menuNames =   { "ROOT",
                                    new Object[] { "Classic Chess",
                                        new Object[] { "Game",
                                            "AI",
                                            "Hotseat",
                                            "Online"
                                        },
                                        "Challenges",
                                        new Object[]{ "Practice",
                                            "Situations",
                                            "Coaching"
                                        },
                                    },
                                    new Object[] { "Fairy Chess",
                                        new Object[] { "Game",
                                            "AI",
                                            "Hotseat",
                                            "Online"
                                        },
                                        "Challenges",
                                        new Object[]{ "Practice",
                                            "Situations",
                                            "Coaching"
                                        },
                                        "Create Pieces"
                                    }
                                };

        currentNode=processHierarchy(menuNames);
        menuTree = new JTree(currentNode);
        initializeButtons(currentNode);
    }


    /**
     * Clicking one of the buttons(which should be in the children of the currentNode), takes you to that node in the tree
     *      setting currentNode to that node and redoing buttons to represent its children.
     */
    public void actionPerformed(ActionEvent ae){
        Button b=(Button)ae.getSource();
        for(int i =0; i<currentNode.getChildCount(); i++){
            if(b.getLabel().equals(currentNode.getChildAt(i)+"")){
                currentNode=(DefaultMutableTreeNode)currentNode.getChildAt(i);
                initializeButtons(currentNode);
            }
        }
    }


    /**
     * will make node out of the first entry in the array, then make nodes out of subsequent entries
     * and make them child nodes of the first one. The process is  repeated recursively for entries that are arrays.
     * this idea of tree declaration as well as the code from the method was lovingly
     * stolen from: http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-JTree.html
     */
    private DefaultMutableTreeNode processHierarchy(Object[] hierarchy) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(hierarchy[0]);
        DefaultMutableTreeNode child;
        for (int i = 1; i < hierarchy.length; i++) {
            Object nodeSpecifier = hierarchy[i];
            if (nodeSpecifier instanceof Object[]) // Ie node with children
                child = processHierarchy((Object[]) nodeSpecifier);
            else
                child = new DefaultMutableTreeNode(nodeSpecifier); // Ie Leaf
            node.add(child);
        }
        return (node);
    }


    /**
     * creates buttons for each child of the given node, labels them with their String value, and adds them to the panel.
     */
    private void initializeButtons(DefaultMutableTreeNode node){
        Button b;
        buttonPanel.removeAll();
        for(int i =0; i<node.getChildCount(); i++){
            b=new Button();
            b.setLabel(""+node.getChildAt(i));
            buttonPanel.add(b);
        }
    }

}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
pocho
  • 31
  • 1
  • Swing GUI objects should be constructed [on the event dispatch thread](http://download.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – trashgod Sep 08 '11 at 03:14
  • *"its not particularly easy to test."* ..`menuTree = new JTree(currentNode);` `menuTree.setVisibleRowCount(6);` `JOptionPane.showMessageDialog(null, new JScrollPane(menuTree));` 2) Why is this an applet? 3) What is the tree for if not to add to the applet? 4) Did you intend to add an action listener to anything? 5) If not, why implement it? 6) Neither the applet nor panel should have the size set. 7) What is your question? – Andrew Thompson Sep 08 '11 at 03:36
  • +1 for [sscce](http://sscce.org/). – trashgod Sep 08 '11 at 04:49

1 Answers1

3

Following @Andrew's helpful outline, a TreeSelectionListener seemed apropos. See How to Use Trees for details. An application seemed easier to debug. Using revalidate() is the key to updating a revised layout.

Menu

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;

/** @see http://stackoverflow.com/questions/7342713 */
public class Menu extends JApplet {

    private JTree menuTree;
    private JPanel buttonPanel;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setTitle("Menu");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                new Menu().initContainer(frame);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    @Override
    public void init() {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                initContainer(Menu.this);
            }
        });
    }

    private void initContainer(Container container) {
        container.setLayout(new GridLayout(1, 0));
        buttonPanel = new JPanel(new GridLayout(0, 1));
        Object[] menuNames = {"ROOT",
            new Object[]{"Classic Chess",
                new Object[]{"Game", "AI", "Hotseat", "Online"},
                "Challenges",
                new Object[]{"Practice", "Situations", "Coaching"}
            },
            new Object[]{"Fairy Chess",
                new Object[]{"Game", "AI", "Hotseat", "Online"},
                "Challenges",
                new Object[]{"Practice", "Situations", "Coaching"},
                "Create Pieces"
            }
        };

        DefaultMutableTreeNode currentNode = processHierarchy(menuNames);
        menuTree = new JTree(currentNode);
        menuTree.setVisibleRowCount(10);
        menuTree.expandRow(2);
        initializeButtons(currentNode);
        container.add(buttonPanel, BorderLayout.WEST);
        container.add(new JScrollPane(menuTree), BorderLayout.EAST);
        menuTree.addTreeSelectionListener(new TreeSelectionListener() {

            @Override
            public void valueChanged(TreeSelectionEvent e) {
                initializeButtons((DefaultMutableTreeNode)
                    menuTree.getLastSelectedPathComponent());
            }
        });
    }

    private DefaultMutableTreeNode processHierarchy(Object[] hierarchy) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(hierarchy[0]);
        DefaultMutableTreeNode child;
        for (int i = 1; i < hierarchy.length; i++) {
            Object nodeSpecifier = hierarchy[i];
            if (nodeSpecifier instanceof Object[]) {
                child = processHierarchy((Object[]) nodeSpecifier);
            } else {
                child = new DefaultMutableTreeNode(nodeSpecifier);
            }
            node.add(child);
        }
        return (node);
    }

    private void initializeButtons(DefaultMutableTreeNode node) {
        Button b;
        buttonPanel.removeAll();
        for (int i = 0; i < node.getChildCount(); i++) {
            b = new Button();
            b.setLabel("" + node.getChildAt(i));
            buttonPanel.add(b);
            buttonPanel.revalidate();
        }
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045