JAVA中分別採用遞迴和非遞迴方法建立選單欄
阿新 • • 發佈:2019-02-16
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);
}