3、Swing布局管理器
在使用 Swing 向容器添加組件時,需要考慮組件的位置和大小。如果不使用布局管理器,則需要先在紙上畫好各個組件的位置并計算組件間的距離,再向容器中添加。這樣雖然能夠靈活控制組件的位置,實現卻非常麻煩。
為了加快開發速度,Java 提供了一些布局管理器,它們可以將組件進行統一管理,這樣開發人員就不需要考慮組件是否會重疊等問題。本節介紹 Swing 提供的 6 種布局類型,所有布局都實現 LayoutManager 接口。
1、 邊框布局管理器
BorderLayout(邊框布局管理器)是 Window、JFrame 和 JDialog 的默認布局管理器。邊框布局管理器將窗口分為 5 個區域:North、South、East、West 和 Center。其中,
- North 表示北,將占據面板的上方;
- Soufe 表示南,將占據面板的下方;
- East表示東,將占據面板的右側;
- West 表示西,將占據面板的左側;
- 中間區域 Center 是在東、南、西、北都填滿后剩下的區域,
如圖 1 所示:
提示:邊框布局管理器并不要求所有區域都必須有組件,如果四周的區域(North、South、East 和 West 區域)沒有組件,則由Center 區域去補充。如果單個區域中添加的不只一個組件,那么后來添加的組件將覆蓋原來的組件,所以,區域中只顯示最后添加的一個組件。
BorderLayout 布局管理器的構造方法如下所示。
- BorderLayout():創建一個 Border 布局,組件之間沒有間隙。
- BorderLayout(int hgap,int vgap):創建一個 Border 布局,其中 hgap
表示組件之間的橫向間隔;vgap 表示組件之間的縱向間隔,單位是像素。
例 1
使用 BorderLayout 將窗口分割為 5 個區域,并在每個區域添加一個標簽按鈕。實現代碼如下:
在該程序中分別指定了 BorderLayout 布局的東、南、西、北、中間區域中要填充的按鈕。該程序的運行結果如圖 2 所示。
如果未指定布局管理器的 NORTH 區域,即將“frame.add(button1,BorderLayout.NORTH);”注釋掉,則 WEST、CENTER 和 EAST 3 個區域將會填充 NORTH 區域,如圖 3 所示。
同理,如果未指定布局管理器的 WEST 區域,即將“frame.add(button2,BorderLayout.WEST);”注釋掉,則 CENTER 區域將會自動拉伸填充 WEST 區域,如圖 4 所示。
2、流式布局管理器
FlowLayout(流式布局管理器)是 JPanel 和 JApplet 的默認布局管理器。
FlowLayout 會將組件按照從上到下、從左到右的放置規律逐行進行定位。與其他布局管理器不同的是,FlowLayout 布局管理器不限制它所管理組件的大小,而是允許它們有自己的最佳大小。
FlowLayout 布局管理器的構造方法如下。
- FlowLayout():創建一個布局管理器,使用默認的居中對齊方式和默認 5 像素的水平和垂直間隔。
- FlowLayout(int align):創建一個布局管理器,使用默認 5 像素的水平和垂直間隔。其中,align表示組件的對齊方式,對齊的值必須是 FlowLayoutLEFT、FlowLayout.RIGHT 和FlowLayout.CENTER,指定組件在這一行的位置是居左對齊、居右對齊或居中對齊。
- FlowLayout(int align, int hgap,int vgap):創建一個布局管理器,其中 align表示組件的對齊方式;hgap 表示組件之間的橫向間隔;vgap 表示組件之間的縱向間隔,單位是像素。
例 2
創建一個窗口,設置標題為“Java第四個GUI程序”。使用 FlowLayout 類對窗口進行布局,向容器內添加 9 個按鈕,并設置橫向和縱向的間隔都為 20 像素。具體實現代碼如下:
上述程序向 JPanel 面板中添加了 9 個按鈕,并使用 HowLayout 布局管理器使 9 個按鈕間的橫向和縱向間隙都為 20 像素。此時這些按鈕將在容器上按照從上到下、從左到右的順序排列,如果一行剩余空間不足容納組件將會換行顯示,最終運行結果如圖 5 所示。
3、卡片布局管理器
CardLayout(卡片布局管理器)能夠幫助用戶實現多個成員共享同一個顯示空間,并且一次只顯示一個容器組件的內容。
CardLayout 布局管理器將容器分成許多層,每層的顯示空間占據整個容器的大小,但是每層只允許放置一個組件。CardLayout 的構造方法如下。
- CardLayout():構造一個新布局,默認間隔為 0。
- CardLayout(int hgap, int vgap):創建布局管理器,并指定組件間的水平間隔(hgap)和垂直間隔(vgap)。
例 3
使用 CardLayout 類對容器內的兩個面板進行布局。其中第一個面板上包括三個按鈕,第二個面板上包括三個文本框。最后調用 CardLayout 類的 show() 方法顯示指定面板的內容,代碼如下:
上述代碼創建了一個卡片式布局的面板 cards,該面板包含兩個大小相同的子面板 p1 和 p2。需要注意的是,在將 p1 和 p2 添加到 cards 面板中時使用了含有兩個參數的 add() 方法,該方法的第二個參數用來標識子面板。當需要顯示某一個面板時,只需要調用卡片式布局管理器的 show() 方法,并在參數中指定子面板所對應的字符串即可,這里顯示的是 p1 面板,運行效果如圖 6 所示。
如果將“cl.show(cards,"card1")”語句中的 card1 換成 card2,將顯示 p2 面板的內容,此時運行結果如圖 7 所示。
4、網格布局管理器
GridLayout(網格布局管理器)為組件的放置位置提供了更大的靈活性。它將區域分割成行數(rows)和列數(columns)的網格狀布局,組件按照由左至右、由上而下的次序排列填充到各個單元格中。
GridLayout 的構造方法如下。
- GridLayout(int rows,int cols):創建一個指定行(rows)和列(cols)的網格布局。布局中所有組件的大小一樣,組件之間沒有間隔。
- GridLayout(int rows,int cols,int hgap,int vgap):創建一個指定行(rows)和列(cols)的網格布局,并且可以指定組件之間橫向(hgap)和縱向(vgap)的間隔,單位是像素。
提示:GridLayout 布局管理器總是忽略組件的最佳大小,而是根據提供的行和列進行平分。該布局管理的所有單元格的寬度和高度都是一樣的。
例 4
使用 GridLayout 類的網格布局設計一個簡單計算器。代碼的實現如下:
上述程序設置面板為 4 行 4 列、間隙都為 5 像素的網格布局,在該面板上包含 16 個按鈕,其橫向和縱向的間隙都為 5。該程序的運行結果如圖 8 所示。
5、網格包布局管理器
GridBagLayout(網格包布局管理器)是在網格基礎上提供復雜的布局,是最靈活、 最復雜的布局管理器。
GridBagLayout 不需要組件的尺寸一致,允許組件擴展到多行多列。每個 GridBagLayout 對象都維護了一組動態的矩形網格單元,每個組件占一個或多個單元,所占有的網格單元稱為組件的顯示區域。
GridBagLayout 所管理的每個組件都與一個 GridBagConstraints 約束類的對象相關。這個約束類對象指定了組件的顯示區域在網格中的位置,以及在其顯示區域中應該如何擺放組件。除了組件的約束對象,GridBagLayout 還要考慮每個組件的最小和首選尺寸,以確定組件的大小。
為了有效地利用網格包布局管理器,在向容器中添加組件時,必須定制某些組件的相關約束對象。GridBagConstraints 對象的定制是通過下列變量實現的。
1. gridx 和 gridy
用來指定組件左上角在網格中的行和列。容器中最左邊列的 gridx 為 0,最上邊行的 gridy 為 0。這兩個變量的默認值是 GridBagConstraints.RELATIVE,表示對應的組件將放在前一個組件的右邊或下面。
2. gridwidth 和 gridheight
用來指定組件顯示區域所占的列數和行數,以網格單元而不是像素為單位,默認值為 1。
3. fill
指定組件填充網格的方式,可以是如下值:
- GridBagConstraints.NONE(默認值)、
- GridBagConstraints.HORIZONTAL(組件橫向充滿顯示區域,但是不改變組件高度)、
- GridBagConstraints.VERTICAL(組件縱向充滿顯示區域,但是不改變組件寬度)、
- GridBagConstraints.BOTH(組件橫向、縱向充滿其顯示區域)。
4. ipadx 和 ipady
指定組件顯示區域的內部填充,即在組件最小尺寸之外需要附加的像素數,默認值為 0。
5. insets
指定組件顯示區域的外部填充,即組件與其顯示區域邊緣之間的空間,默認組件沒有外部填充。
6. anchor
指定組件在顯示區域中的擺放位置。可選值有
-
GridBagConstraints.CENTER(默認值)、
-
GridBagConstraints.NORTH、
-
GridBagConstraints.NORTHEAST、
-
GridBagConstraints.EAST、
-
GridBagConstraints.SOUTH、
-
GridBagConstraints.SOUTHEAST、
-
GridBagConstraints.WEST、
-
GridBagConstraints.SOUTHWEST 、
-
GridBagConstraints.NORTHWEST。
7. weightx 和 weighty
用來指定在容器大小改變時,增加或減少的空間如何在組件間分配,默認值為 0,即所有的組件將聚攏在容器的中心,多余的空間將放在容器邊緣與網格單元之間。weightx 和 weighty 的取值一般在 0.0 與 1.0 之間,數值大表明組件所在的行或者列將獲得更多的空間。
例 5
創建一個窗口,使用 GridBagLayout 進行布局,實現一個簡易的手機撥號盤。這里要注意如何控制行內組件的顯示方式以及使用 GridBagConstraints.REMAINDER 來控制一行的結束。代碼的實現如下:
在上述程序中創建了一個 makeButton() 方法,用來將 JButton 組件添加到 JFrame 窗口中。
在 main() 方法中分別創建了 GridBagLayout 對象和 GridBagConstraints 對象,然后設置 JFrame 窗口的布局為 GridBagLayout,并設置了 GridBagConstraints 的一些屬性。
接著將 JTextField 組件添加至窗口中,并通知布局管理器的 GridBagConstraints 信息。
在接下來的代碼中,調用 makeButton() 方法向 JFrame 窗口填充按鈕,并使用 GridBagConstraints. REMAINDER 來控制結束行。
當一行結束后,重新設置 GridBagConstraints 對象的 gridwidth 為 1。最后設置 JFrame 窗口為可見狀態,程序運行后的撥號盤效果如圖 9 所示。
6、盒布局管理器
BoxLayout(盒布局管理器)通常和 Box 容器聯合使用,Box 類有以下兩個靜態方法。
- createHorizontalBox():返回一個 Box 對象,它采用水平 BoxLayout,即 BoxLayout
沿著水平方向放置組件,讓組件在容器內從左到右排列。 - createVerticalBox():返回一個 Box 對象,它采用垂直 BoxLayout,即 BoxLayout
沿著垂直方向放置組件,讓組件在容器內從上到下進行排列。
Box 還提供了用于決定組件之間間隔的靜態方法:
- static Component createHorizontalGlue()---- 創建一個不可見的、可以被水平拉伸和收縮的組件
- static Component createVerticalGlue()---- 創建一個不可見的、可以被垂直拉伸和收縮的組件
- static Component createHorizontalStrut(int width)---- 創建一個不可見的、固定寬度的組件
- static Component createVerticalStrut(int height) ----創建一個不可見的、固定高度的組件
- static Component createRigidArea(Dimension d) ----創建一個不可見的、總是具有指定大小的組件
BoxLayout 類只有一個構造方法,如下所示。
BoxLayout(Container c,int axis)其中,參數 Container 是一個容器對象,即該布局管理器在哪個容器中使用;
第二個參數為 int 型,用來決定容器上的組件水平(X_AXIS)或垂直(Y_AXIS)放置,可以使用 BoxLayout 類訪問這兩個屬性。
例 6
使用 BoxLayout 類對容器內的 4 個按鈕進行布局管理,使兩個按鈕為橫向排列,另外兩個按鈕為縱向排列,代碼如下:
在程序中創建了 4 個 JButton 按鈕和兩個 Box 容器(橫向 Box 容器和縱向 Box 容器),并將前兩個 JButton 按鈕添加到橫向 Box 容器中,將后兩個 JButton 容器添加到縱向 Box 容器中。程序的運行結果如圖 10 所示。
提示:使用盒式布局可以像使用流式布局一樣簡單地將組件安排在一個容器內。包含盒式布局的容器可以嵌套使用,最終達到類似于無序網格布局那樣的效果,卻不像使用無序網格布局那樣麻煩。
總結
以上是生活随笔為你收集整理的3、Swing布局管理器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2、Java Swing JFrame和
- 下一篇: 4、Java Swing JLable: