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