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要仔细研究发现东西也不少!