1. 程式人生 > >JAVA中分別採用遞迴和非遞迴方法建立選單欄

JAVA中分別採用遞迴和非遞迴方法建立選單欄

1.首先編寫一個建立樹的方法。該方法中傳入的形參為包含選單欄資訊的列表,返回值為選單樹的根結點。

public static final DefaultMutableTreeNode createTree(List<Node> list) {
        DefaultMutableTreeNode tree = new DefaultMutableTreeNode("root");
        Map<String, DefaultMutableTreeNode> map = getTreeNodeMap(list);
        while (list.size() > 0) {
            Node n = list.get(list.size() - 1);
            if (map.get(n.getSuperid()) == null) {
                tree.add(map.get(n.getId()));
                list.remove(n);
            } else {
                DefaultMutableTreeNode treeNode = map.get(n.getSuperid());
                treeNode.add(map.get(n.getId()));
                list.remove(n);
            }
        }
        return tree;
    }

    public static final Map<String, DefaultMutableTreeNode> getTreeNodeMap(
            List<Node> nodes) {
        Map<String, DefaultMutableTreeNode> treeNodeMap = new HashMap<>();
        if (nodes == null) {
            return null;
        }
        Iterator I = nodes.iterator();
        while (I.hasNext()) {
            Node n = (Node) I.next();
            treeNodeMap.put(n.getId(), new DefaultMutableTreeNode(n.getId()));
        }
        treeNodeMap.put("root", new DefaultMutableTreeNode("root"));
        return treeNodeMap;
    }

2.編寫建立選單欄的函式。首先介紹採用非遞迴方法建立選單欄。該方法中傳入的形參為選單樹的根結點,返回值為JMenuBar。
public static JMenuBar createMenu(DefaultMutableTreeNode tree) {
        if (!tree.isRoot()) {
            return null;
        }
        JMenuBar menuBar = new JMenuBar();
        JMenuItem menuItem = null;
        Stack<TreeNode> stack = new Stack<>();
        Map<String, JMenuItem> menuMap = new HashMap<>();
        stack.push(tree);

        while(!stack.empty()) {
            TreeNode popNode = stack.pop();

            if(!((DefaultMutableTreeNode)popNode).isRoot()) {
                if(((DefaultMutableTreeNode)popNode.getParent()).isRoot()) {
                    if(popNode.isLeaf()) {
                        menuItem = new JMenuItem(popNode.toString());
                    } else {
                        menuItem = new JMenu(popNode.toString());
                    }
                    menuBar.add(menuItem);
                } else {
                    if(popNode.isLeaf()) {
                        menuItem = new JMenuItem(popNode.toString());
                    } else {
                        menuItem = new JMenu(popNode.toString());
                    }
                    menuMap.get(popNode.getParent().toString()).add(menuItem);
                }
                menuMap.put(popNode.toString(), menuItem);
            }

            int count = popNode.getChildCount();
            for(int i = 0; i < count; i++) {
                stack.push(popNode.getChildAt(i));
            }
        }

        return menuBar;
    }

3.採用遞迴方式建立選單欄。該函式傳入的形參為選單樹的根結點和當前選單的父節點。
public static void createMenu1(DefaultMutableTreeNode node, JComponent jParentMenu) {
        JMenuItem menuItem = null;
        if(!node.isRoot()) {
            if(node.isLeaf()) {
                menuItem = new JMenuItem(node.toString());
            } else {
                menuItem = new JMenu(node.toString());
            }
            jParentMenu.add(menuItem);
        }

        int count = node.getChildCount();
        for(int i = count - 1; i >= 0; i--) {
            createMenu1((DefaultMutableTreeNode)node.getChildAt(i), menuItem == null ? jParentMenu : menuItem);
        }
    }

4.上述方法中採用的選單結點資訊類(Node)如下:該類中實現了Comparable介面,用來排序。
public class Node implements Comparable<Node> {
    private String id;
    private String name;
    private String superid;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSuperid() {
        return superid;
    }
    public void setSuperid(String superid) {
        this.superid = superid;
    }

    @Override
    public int compareTo(Node o) {
        return this.id.compareTo(o.getId());
    }
}

5.測試方法如下:
public static void main(String[] args) {
        List<Node> list = new ArrayList<Node>();
        Node n = new Node();
        n.setId("01");
        n.setName("01");
        n.setSuperid(null);
        list.add(n);
        n = new Node();
        n.setId("02");
        n.setName("02");
        n.setSuperid(null);
        list.add(n);
        n = new Node();
        n.setId("0102");
        n.setName("0102");
        n.setSuperid("01");
        list.add(n);
        n = new Node();
        n.setId("0101");
        n.setName("0101");
        n.setSuperid("01");
        list.add(n);
        n = new Node();
        n.setId("010101");
        n.setName("010101");
        n.setSuperid("0101");
        list.add(n);
        n = new Node();
        n.setId("010102");
        n.setName("010102");
        n.setSuperid("0101");
        list.add(n);
        n = new Node();
        n.setId("0201");
        n.setName("0201");
        n.setSuperid("02");
        list.add(n);
        n = new Node();
        n.setId("01010201");
        n.setName("01010201");
        n.setSuperid("010102");
        list.add(n);

        Collections.sort(list);

        DefaultMutableTreeNode tree = createTree(list);

        //showTree(tree);
        JMenuBar menuBar = createMenu(tree);
        //JMenuBar menuBar = new JMenuBar();
        //createMenu1(tree, menuBar);
        JFrame frame = new JFrame();
        frame.setJMenuBar(menuBar);
        frame.setSize(600, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }