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);
}