Java 程序通過jvm可以很好的移植到其他平台上,但是java 生成的圖形界面樣式,在不使用布局的情況下,往往需要重新設定大小,才能在新的平台上調整到最佳樣式。這是由於組件的最佳大小 往往是與平台相關的。不同平台上,相同的內容大小可能不一樣.java專門提供了LayoutManager(布局管理器)來更好的進行布局管理,使組件的大小和位置調整到最佳。(包括控件無遮擋,無冗余空間)。
(一) 再開始講解布局之前,這里先普及一下關於布局中的一些常用知識。
1、容器 Container 做過圖形界面繪制工作的人基本都知道這個容器的概念。如果第一次接觸的話,可以簡單的直接把他理解為是一塊面板,可以在上面畫控件的東西。 常用的Container 包括:window panel scrollPane 其中Window 又包括 Frame(窗體) Dialog(對話框)
2、對容器的布局設置 Container.setLayoutManager(new layoutManager());
(二) Java 常用的有 5+1+1種布局。
1)其中5代表 awt布局有5種分別是 FlowLayout 、BorderLayout、GridLayout、GridBagLayout、CardLayout 下邊依次來介紹每種布局
(1)FowLayout 流布局
什么是流布局呢,flow 代表流 水流,FlowLayout也就是就是(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )控件就像流水(隊列)一樣向某個排列,當遇到邊界的時候,就折回從下一行繼續排隊。就像軍訓的時候人員一排一排的站好,當一排人數滿的時候,就另起一行繼續排隊。
默認情況下,FlowLayout 布局管理器都是從左向右排列所有組件的。
樣式如下圖
常用的構造函數有三種
FlowLayout()
FlowLayout(int align)
FlowLayout(int align, int hgap, int vgap)
參數解釋:
1、其中align 代表的是對齊方式,包括三種,值作為靜態常量保存在 FlowLayout中了
FlowLayout.LEFT 從左向右對齊
FlowLayout.RIGHT從右向左對齊
FlowLayout.CENTER從中間向兩邊對齊
前兩種類似於軍訓的向左看齊、向右看齊,最后一種類似於照相時,以每排中間為基准,兩邊向中間靠攏。
2、hgap,控件之間的水平間距 ps.注意此處及下文中的間距都是指的任意一個控件與其周邊控件控件的水平和垂直的距離
3、vgap,控件之間的垂直間距
1 import java.awt.FlowLayout;
2 import javax.swing.JFrame;
3 import javax.swing.JButton;
4
5
6 public class FlowLayoutDemo
7 {
8 public static void main(String[] args)
9 {
10 JFrame f=new JFrame("FlowLayout");
11 f.setLayout(new FlowLayout());
12 for(int i=0;i<7;i++)
13 {
14 JButton btn=new JButton("Button"+i);
15 f.add(btn);
16 }
17 f.setSize(300,150);
18 f.setVisible(true);
19 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
20 }
21 }
顯示效果:
2)BorderLayout 邊框布局
Bordern n.邊境;邊界;國界 BorderLayout 也就是把容器通過邊界划分成幾個區域,這幾個區域各自始終存在, 並且數量始終為5個:東、西、南、北、中(也就是 EAST/WEST/SOUTH/NORTH/CENTER),區域的相對位置如下圖.添加的控件可以被指定放置在區域中的任何一個位置。
這個布局有四點需要注意
1、當布局的大小發生調整時 NORTH/SOUTH/CENTER進行水平調整 EAST/WEST/CENTER進行垂直調整 比如說拉寬窗體,那么只有NORTH/SOUTH/CENTER 這三個區域的寬度會變大,WEST和EAST的寬度不發生改變
2、當向BorderLayout布局的容器中添加控件時,需要指定控(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )件要被放置在哪個區域中。否則,系統方法會默認將該控件放置在center區域。
3、每個區域只能添加一個控件或者一個容器。如果反復添加,后續添加的控件會覆蓋前邊添加的控件。
4、Frame、Dialog、ScrollPane默認使用的都是這個布局,所以直接向這幾個容器中添加控件,最終只會顯示一個控件
常用的構造函數有兩種
BorderLayout()
BorderLayout(int hgap, int vgap)
ps. hgap,區域之間的水平間距。vgap,區域之間的垂直間距。
1 import java.awt.BorderLayout;
2 import javax.swing.JFrame;
3 import javax.swing.JButton;
4
5
6 public class BorderLayoutDemo
7 {
8 public static void main(String[] args)
9 {
10 JFrame f=new JFrame("BorderLayout");
11 JButton btn=new JButton("BorderLayout.NORTH");
12 f.add(btn,BorderLayout.NORTH); //NORTH、SOUTH、EAST、WEST、CENTER在BorderLayout中被設置為靜態變量了
13 btn=new JButton("BorderLayout.SOUTH");
14 f.add(btn,BorderLayout.SOUTH);
15 btn=new JButton("BorderLayout.EAST");
16 f.add(btn,BorderLayout.EAST);
17 btn=new JButton("BorderLayout.West");
18 f.add(btn,BorderLayout.WEST);
19 btn=new JButton("BorderLayout.CENTER");
20 f.add(btn,BorderLayout.CENTER);
21 f.pack();
22 f.setVisible(true);
23 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
24 }
25 }
前文中介紹了FlowLayout和BorderLayout 本文我們將會繼續介紹java中的布局方式
(3)GridLayout 網格布局
這種布局會將整個容器划分成M行*N列的網格。
如下圖:
由模型圖我們可以知道這種布局,類似於我們常見的掃雷、計算器等軟件的布局。
這種布局的構造函數有三種
1 GridLayout() //一行一列
2
3 GridLayout(int rows, int cols)
4
5 GridLayout(int rows, int cols, int hgap, int vgap)//hgap 水平間距, vgap垂直間距
在向這種容器中添加控件時,會以向左后右,先上后下的順序添加(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )控件。 而不能在指定的位置中添加控件,換言之控件之間不能留有空白。 下面我們來看代碼
1 import java.awt.*;
2 import javax.swing.*;
3
4 class GridFrame extends JFrame
5 {
6 JPanel panel=new JPanel(new GridLayout(4,4,3,3));//構造指定布局的容器
7 String str[]={"7","8","9","/","4","5","6","*","1","2","3","-","0",".","=","+"};
8 public GridFrame(String name)
9 {
10 super(name);
11 setLayout(new BorderLayout());
12 JButton btnArray[];
13 btnArray=new JButton[str.length];
14 for(int i=0;i<str.length;i++)
15 {
16 btnArray[i]=new JButton(str[i]);
17 panel.add(btnArray[i]);
18 }
19 setVisible(true);
20 setSize(250,200);
21 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
22 setVisible(true);
23 }
24
25 public static void main(String[] args)
26 {
27 GridFrame gf=new GridFrame("網格布局計算機!");
28 }
29
30 }
顯示效果如下圖
(4)GridBagLayout
GridBagLayout也是一種表格,但是可以通過設定規則更自由的將控件綁定到容器上:
如下圖:
將容器切割為若干個小的格子Cell,然后向這些Cell中添加控件,同時可以在某一個(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )方向上連續的幾個Cell進行拼接,組成一個大的Cell放置控件。
操作步驟如下:
(1)new GridBagLayout() 設置到指定容器上。
(2)GridBagConstraint gbc 新增這樣的一個容器規則。(注意Constraint是規則、約束、條件的意思)
設定的參數規則如下
gridx gridy 索引
gridwidth gridheight 跨越的索引
fill 是否動態擴充
weightx、weighty 擴大的權重
(3)gb.setConstraints(控件,gbc) 將控件和規則綁定起來
(4)constainer.add(c) 添加容器,然后將控件添加到容器上。
同時gbc 可以重用,反復的設定骨子額,綁定規則,添加容器
重復 2、3、4步
請參照 如下代碼 ,重點注意 addComponent()方法:
1 public class NumberPad {
2 private static final Insets insets = new Insets(0, 0, 0, 0);
3 public static void main(final String args[]) {
4 final JFrame frame = new JFrame("NumberPad");
5 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗口操作
6 frame.setLayout(new GridBagLayout());//框架布局
7 JButton button;
8 //下面利用設立的類對按鍵進行布局
9 //第一行
10 button = new JButton("Num");
11 addComponent(frame, button, 0, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
12 button = new JButton("/");
13 addComponent(frame, button, 1, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
14 button = new JButton("*");
15 addComponent(frame, button, 2, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
16 button = new JButton("-");
17 addComponent(frame, button, 3, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
18 //第二行
19 button = new JButton("1");
20 addComponent(frame, button, 0, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
21 button = new JButton("2");
22 addComponent(frame, button, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
23 button = new JButton("3");
24 addComponent(frame, button, 2, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
25 button = new JButton("+");
26 addComponent(frame, button, 3, 1, 1, 2, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
27 // 第三行
28 button = new JButton("4");
29 addComponent(frame, button, 0, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
30 button = new JButton("5");
31 addComponent(frame, button, 1, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
32 button = new JButton("6");
33 addComponent(frame, button, 2, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
34 //第四行
35 button = new JButton("7");
36 addComponent(frame, button, 0, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
37 button = new JButton("8");
38 addComponent(frame, button, 1, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
39 button = new JButton("9");
40 addComponent(frame, button, 2, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
41 button = new JButton("Enter");
42 addComponent(frame, button, 3, 3, 1, 2, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
43 //第五行
44 button = new JButton("0");
45 addComponent(frame, button, 0, 4, 2, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
46 button = new JButton(".");
47 addComponent(frame, button, 2, 4, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
48 frame.setSize(250,250);
49 frame.setVisible(true);
50 }
51
52 private static void addComponent(Container container, Component component, int gridx, int gridy,
53 int gridwidth, int gridheight, int anchor, int fill) {
54 GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0,
55 anchor, fill, insets, 0, 0);//建立網格包對象
56 container.add(component, gbc);//添加到容器中
57 }
ps 此代碼來自http://blog.sina.com.cn/s/blog_6cea57330100pwvq.html
這里有幾點要注意的
(1)控制動態擴充的fill參數,有四個值分別為 水平擴充、垂直擴充、水平垂直擴充、不擴充。大家根據自己的實際情況來選擇
(2)weightx、weighty 是擴大的權重,這個權重表示的是,當橫向(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )或縱向擴大N的倍數后,那么他占的比重是多少。這里要小心,就是權重大的話,如果往大拖容器size,那么這個控件增長的快,同時當size變小時,權重大的也縮小的更快。所以如果要想讓權重大的控件始終大時,需要將幾個控件的初始size設定的非常小,這樣所有的控件都是在拖大的狀態了。