最近要完成一个需求:用swing做个树状菜单,含二级菜单,点击一级菜单展开二级菜单,且二级菜单数目超过预览视图会出现滚动条。由于swing研究的少,花了不少精力!
先看下测试效果图:
完整源码:
1 package com.xuwei.test2;
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.GridLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
9 import javax.swing.JButton;
10 import javax.swing.JFrame;
11 import javax.swing.JPanel;
12 import javax.swing.JScrollPane;
15 public class TestFrm4 extends JFrame{
16 private JButton btn1,btn2,btn3,btn4,btn5;
17 private JPanel pNorth,pSouth,subMenuContainer;
18 private JScrollPane pCenter;
19 private JButton[] btn = null;
20 private static boolean expand=false;
22 public TestFrm4(){
23 btn1=new JButton("Grade1 menu1");
24 btn1.setBackground(Color.CYAN);
25 btn2=new JButton("Grade1 menu2");
26 btn2.setBackground(Color.CYAN);
27 btn3=new JButton("Grade1 menu3");
28 btn3.setBackground(Color.CYAN);
29 btn3.addActionListener(new ActionHandler());
31 btn4=new JButton("Grade1 menu4");
32 btn4.setBackground(Color.CYAN);
33 btn5=new JButton("Grade1 menu5");
34 btn5.setBackground(Color.CYAN);
35 pNorth=new JPanel();
36 pNorth.setLayout(new GridLayout(3,1));
37 pSouth=new JPanel();
38 pSouth.setLayout(new GridLayout(2,1));
39 subMenuContainer=new JPanel();
40 subMenuContainer.setLayout(new GridLayout(25,1));
42 btn=new JButton[25];
43 for(int i=0;i<btn.length;i++){
44 btn[i]=new JButton("[菜单"+i+"]");
45 btn[i].setBackground(Color.WHITE);
46 }
48 this.setLayout(new BorderLayout());
50 pNorth.add(btn1); pNorth.add(btn2); pNorth.add(btn3);
51 for(int i=0;i<btn.length;i++){
52 subMenuContainer.add(btn[i]);
53 }
54 pCenter=new JScrollPane(subMenuContainer);
56 pSouth.add(btn4);pSouth.add(btn5);
57 this.add(pNorth,"North");
58 this.add(pCenter,"Center");
59 this.add(pSouth,"South");
61 this.setVisible(true);
62 this.setSize(500,600);
63 this.setResizable(false);
64 this.setLocationRelativeTo(null);
65 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
67 }
71 private class ActionHandler implements ActionListener{
73 @Override
74 public void actionPerformed(ActionEvent e) {
75 if(btn3==e.getSource()){
76 if(expand){//折叠
77 pNorth.setLayout(new GridLayout(3,1));
78 pNorth.remove(btn4);pNorth.remove(btn5);
79 pSouth.add(btn4);pSouth.add(btn5);
80 for(int i=0;i<btn.length;i++){
81 subMenuContainer.add(btn[i]);
82 }
83 validate();
84 getContentPane().repaint();
85 expand=false;
86 }else{//展开
87 for(int i=0;i<btn.length;i++){
88 subMenuContainer.remove(btn[i]);
89 }
90 pSouth.removeAll();
91 pNorth.setLayout(new GridLayout(5,1));
92 pNorth.add(btn4);
93 pNorth.add(btn5);
94 pNorth.repaint();
95 pCenter.repaint();
96 pSouth.repaint();
97 validate();
98 getContentPane().repaint();
99 expand=true;
100 }
101 }
102 }
104 }
106 public static void main(String[] args) {
108 new TestFrm4();
109 }
111 }
这里频繁添加删除组件需要及时刷新界面,swing有几个方法要反复调用:
repaint(),validate(),invalidate(),doLayout().
之前我由于没调用validate()导致界面刷新出现很多问题!
swing要仔细研究发现东西也不少!