Java Swing编程之仿js树状折叠菜单

最近要完成一个需求:用swing做个树状菜单,含二级菜单,点击一级菜单展开二级菜单,且二级菜单数目超过预览视图会出现滚动条。由于swing研究的少,花了不少精力!

先看下测试效果图:

收起图:

展开图:

完整源码:

  1 package com.xuwei.test2;
  2 
  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;
  8 
  9 import javax.swing.JButton;
 10 import javax.swing.JFrame;
 11 import javax.swing.JPanel;
 12 import javax.swing.JScrollPane;
 13 
 14 
 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;
 21     
 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());
 30         
 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));
 41      
 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         }
 47         
 48         this.setLayout(new BorderLayout());
 49         
 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);
 55         
 56         pSouth.add(btn4);pSouth.add(btn5);
 57         this.add(pNorth,"North");
 58         this.add(pCenter,"Center");
 59         this.add(pSouth,"South");
 60        
 61         this.setVisible(true);
 62         this.setSize(500,600);
 63         this.setResizable(false);
 64         this.setLocationRelativeTo(null);
 65         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 66         
 67     }
 68     
 69     
 70     
 71     private class ActionHandler implements ActionListener{
 72 
 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         }
103         
104     }
105     
106     public static void main(String[] args) {
107        
108         new TestFrm4();
109     }
110 
111 }

这里频繁添加删除组件需要及时刷新界面,swing有几个方法要反复调用:

repaint(),validate(),invalidate(),doLayout().

之前我由于没调用validate()导致界面刷新出现很多问题!

swing要仔细研究发现东西也不少!

 

posted on 2015-04-29 12:51  DavidXu2014  阅读(2997)  评论(0编辑  收藏  举报