您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Java圖形界面開發(fā)中的高級(jí)Swing容器怎么用,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
我們將會(huì)了解一些構(gòu)建在這些布局管理器之上的容器以及其他的一些無需布局管理器的容器。
我們的探討由Box類開始,我們將會(huì)發(fā)現(xiàn)使用BoxLayout管理器來創(chuàng)建一個(gè)單行或單列組件的最好方法。接下來我們會(huì)了解JSplitPane容器,他類似于其中只有兩個(gè)組件的特殊的Box。JSplitPane提供了一個(gè)分隔欄,用戶可以拖動(dòng)這個(gè)分隔欄來調(diào)整組件的大小以滿足各自的需求。
然后我們會(huì)探討JTabbedPane容器,其工作方工式類似于一個(gè)由CardLayout布局管理器管理的容器,所不同的是容器內(nèi)建的標(biāo)簽可以使得我們由一個(gè)卡片移動(dòng)到一個(gè)卡片。我們也可以使用JTabbedPane創(chuàng)建多個(gè)屏幕,屬性頁對(duì)話框用于用戶輸入。
最后討論的兩個(gè)高級(jí)Swing容器是JScrollPane與JViewport。這兩個(gè)組件都提供了在有限的屏幕真實(shí)狀態(tài)之內(nèi)顯示大組件集合的能力。JScrollPane為顯示區(qū)域添加滾動(dòng)條,從而我們可以在一個(gè)小區(qū)域內(nèi)在大組件周圍移動(dòng)。事實(shí)上,JScrollPane使用JViewport來分割本看不見的大組件部分。
下面我們就開始了解第一個(gè)容器,Box類。
11.1 Box類
作為JComponent類的子類,Box類是借助于BoxLayout管理器創(chuàng)建單行或單列組件的一個(gè)特殊Java Container。Box容器的作用類似于JPanel(或Panel),但是具有一個(gè)不同的默認(rèn)布局管理器,BoxLayout。在Box之外使用BoxLayout有一些麻煩,而Box簡化了BoxLayout的使用。我們只需三步就可以將BoxLayout管理器與容器相關(guān)聯(lián):手動(dòng)創(chuàng)建容器,創(chuàng)建布局管理器,然后將管理器與容器相關(guān)聯(lián)。當(dāng)我們創(chuàng)建一個(gè)Box的實(shí)例時(shí),我們一次就執(zhí)行了這三個(gè)步驟。另外,我們可以使用Box的名為Box.Filler的內(nèi)聯(lián)類來更好的放置容器內(nèi)的組件。
11.1.1 創(chuàng)建Box
我們有三種方法來創(chuàng)建Box,一個(gè)構(gòu)造函數(shù)以及兩個(gè)靜態(tài)工廠方法:
public Box(int direction) Box horizontalBox = new Box(BoxLayout.X_AXIS); Box verticalBox = new Box(BoxLayout.Y_AXIS); public static Box createHorizontalBox() Box horizontalBox = Box.createHorizontalBox(); public static Box createVerticalBox() Box verticalBox = Box.createVerticalBox();
注意 ,Box類并沒有被設(shè)計(jì)用來作為JavaBean組件使用。在IDE中這個(gè)容器的使用十分笨拙。
不經(jīng)常使用的構(gòu)造函數(shù)需要布局管理器主坐標(biāo)的方向。這個(gè)方向是通過BoxLayout的兩個(gè)常量來指定的:X_AXIS或Y_AXIS,分別用來創(chuàng)建水平或垂直盒子。我們無需手動(dòng)指定方向,我們可以簡單的通過所提供的工廠方法來創(chuàng)建所需方向的盒子:createHorizontalBox()或createVerticalBox()。
使用JLabel,JTextField與JButton填充一個(gè)水平與垂直Box演示了BoxLayout的靈活性,如圖11-1所示。
對(duì)于水平容器,標(biāo)簽與按鈕以其最優(yōu)的寬度顯示,因?yàn)樗麄兊淖畲蟪叽缗c最優(yōu)尺寸相同。文本域使用余下的空間。
在垂直容器中,標(biāo)簽與按鈕的尺寸也是他們的最優(yōu)尺寸,因?yàn)樗麄兊淖畲蟪叽缫廊慌c他們的最優(yōu)尺寸相同。文本的高度填充了標(biāo)簽與按鈕沒有使用的高度,而其寬度與容器的寬度相同。
用于創(chuàng)建圖11-1所示屏幕的源碼顯示在列表11-1中。
package swingstudy.ch21; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; public class BoxSample { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Runnable runner = new Runnable() { public void run() { JFrame verticalFrame = new JFrame("Vertical"); verticalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Box verticalBox = Box.createVerticalBox(); verticalBox.add(new JLabel("Top")); verticalBox.add(new JTextField("Middle")); verticalBox.add(new JButton("Bottom")); verticalFrame.add(verticalBox, BorderLayout.CENTER); verticalFrame.setSize(150, 150); verticalFrame.setVisible(true); JFrame horizontalFrame = new JFrame("Horizontal"); horizontalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Box horizontalBox = Box.createHorizontalBox(); horizontalBox.add(new JLabel("Left")); horizontalBox.add(new JTextField("Middle")); horizontalBox.add(new JButton("Right")); horizontalFrame.add(horizontalBox, BorderLayout.CENTER); horizontalFrame.setSize(150, 150); horizontalFrame.setVisible(true); } }; EventQueue.invokeLater(runner); } }
11.1.2 Box屬性
如表11-1所示,Box只有兩個(gè)屬性。盡管布局屬性由其父類Container繼承了setLayout(LayoutManager)方法,但是如果在Box對(duì)象上調(diào)用,這個(gè)類會(huì)拋出一個(gè)AWTError。一旦BoxLayout管理器在其構(gòu)造函數(shù)中被設(shè)置,那么就能再改變,其方向也不能改變。
11.1.3 使用Box.Filer
Box類具有一個(gè)內(nèi)聯(lián)類Box.Filler,可以幫助我們創(chuàng)建不可見的組件從而更好的為采用BoxLayout布局管理器的容器內(nèi)的組件進(jìn)行位置布局。通過直接操作所創(chuàng)建組件的最小,最大與最優(yōu)尺寸,我們可以創(chuàng)建可以增長來填充未用的空間或是保持固定尺寸的組件,從而屏幕更為用戶所接受。
注意,由技術(shù)上來說,Box.Filler的使用并沒有局限于使用BoxLayout布局管理器的容器。我們可以將其用在其他任何使用Component的地方。只是組件是不可見的。
我們無需直接使用Box.Filler類,Box類的一些靜態(tài)方法可以幫助我們創(chuàng)建合適的填充器組件。工廠方法可以使得我們通過類型對(duì)組件進(jìn)行分類,而不是通過最小值,最大值或是最優(yōu)尺寸進(jìn)行分類。我們將會(huì)在接下來的兩節(jié)中了解這些方法。
如果我們對(duì)類定義感興趣,Box.Filler的類定義顯示如下。類似于Box類,Box.Filler本來也不是作為JavaBean組件來使用的。
public class Box.Filler extends Component implements Accessible { // Constructors public Filler(Dimension minSize, Dimension prefSize, Dimension maxSize); // Properties public AccessibleContext getAccessibleContext(); public Dimension getMaximumSize(); public Dimension getMinimumSize(); public Dimension getPreferredSize(); // Others protected AccessibleContext accessibleContext; public void changeShape(Dimension minSize, Dimension prefSize, Dimension maxSize); }
11.1.4 創(chuàng)建擴(kuò)展區(qū)域
如果一個(gè)組件具有較小的最小尺寸與最優(yōu)尺寸,而最大尺寸要大于屏幕尺寸,組件可以在一個(gè)或是兩個(gè)方向上進(jìn)行擴(kuò)展以占用容器中組件之間的未用空間。在Box的情況下,或者更確切的說,布局管理器為BoxLayout的容器,擴(kuò)展出現(xiàn)在布局管理器初始選擇的方向上(BoxLayout.X_AXIS或BoxLayout.Y_AXIS)。對(duì)于水平的盒子,擴(kuò)展影響了組件的寬度。對(duì)于垂直的盒子,擴(kuò)展反映在組件的高度上。
通常為這種擴(kuò)展組件類型指定的名字為膠水(glue)。glue的兩種類型為獨(dú)立于方向的glue與方向相關(guān)的glue。下面的Box工廠方法用于創(chuàng)建膠合組件:
public static Component createGlue() // Direction independent Component glue = Box.createGlue(); aBox.add(glue); public static Component createHorizontalGlue(); // Direction dependent: horizontal Component horizontalGlue = Box.createHorizontalGlue(); aBox.add(horizontalGlue); public static Component createVerticalGlue() // Direction dependent: vertical Component verticalGlue = Box.createVerticalGlue(); aBox.add(verticalGlue);
一旦我們創(chuàng)建了glue,我們就可以像添加其他的組件一樣將其添加到容器中,通過Container.add(Component)或是其他的add()方法。glue可以使得我們?cè)谌萜鲀?nèi)對(duì)齊組件,如圖11-2所示。
我們可以將膠合組件添加到任何其布局管理器考慮到組件的最小尺寸,最大尺寸與最優(yōu)尺寸的容器中,例如BoxLayout。例如,圖11-3演示了當(dāng)我們將一個(gè)膠合組件添加到JMenuBar而在最后一個(gè)JMenu之前的樣子。因?yàn)镴MenuBar的布局管理器為BoxLayout(實(shí)際上是子類javax.swing.plaf.basic.DefaultMenuLayout),這一操作可以將最后一個(gè)菜單推到工具欄的右邊,類似于Motif/CDE風(fēng)格的幫助菜單。
注意,我們推薦避免使用膠合組件的這種功能來設(shè)置菜單欄上的菜單。事實(shí)上JMenuBar的public void sethelpMenu(JMenu menu)將會(huì)實(shí)現(xiàn)這種行為而且不會(huì)拋出Error。當(dāng)然,我們中的許多人仍在等待這種操作。
11.1.5 創(chuàng)建固定區(qū)域
因?yàn)槟z合組件會(huì)擴(kuò)展來填充可用的空間,如果我們希望組件之間有一段固定的距離,我們需要?jiǎng)?chuàng)建一個(gè)固定組件,或strut。當(dāng)我們這樣做時(shí),我們需要指定strut的尺寸。strut可以是二維的,需要我們指定組件的寬度或調(diào)試;或者也可以是一維的,需要我們指定寬度或高度。
public static Component createRigidArea(Dimension dimension) // Two-dimensional Component rigidArea = Box. createRigidArea(new Dimension(10, 10)); aBox.add(rigidArea); public static Component createHorizontalStrut(int width) // One-dimensional: horizontal Component horizontalStrut = Box. createHorizontalStrut(10); aBox.add(horizontalStrut); public static Component createVerticalStrut(int height) // One-dimensional: vertical Component verticalStrut = Box. createVerticalStrut(10); aBox.add(verticalStrut);
注意,盡管使用createGule()方法創(chuàng)建的方向無關(guān)的膠合組件在我們修改容器方向時(shí)并沒有副作用,然而創(chuàng)建固定區(qū)域會(huì)在修改坐標(biāo)時(shí)引起布局問題。(想像一下拖動(dòng)菜單欄)這是因?yàn)榻M件具有一個(gè)最小尺寸。使用createRigidArea()方法并不推薦,除非我們確實(shí)需要一個(gè)二維的空組件。
圖11-4顯示了一些固定組件。注意,我們可以變化不同的組件之間的固定距離,而且容器最末的固定組件并沒有效果。在用戶調(diào)整屏幕之后,組件之間的固定距離會(huì)保持不變,如圖11-4所示。
11.2 JSplitPane類
類似于Box容器,JSplitPane容器允許我們?cè)趩涡谢騿瘟兄酗@示組件。然而Box可以包含任意數(shù)量的組件,JSplitPane只可以用來顯示兩個(gè)組件。組件可以變化尺寸并通過一個(gè)可移動(dòng)的分隔欄進(jìn)行分隔。分隔欄可以使得用戶可以通過拖拽分隔欄來調(diào)整所包含組件的尺寸。圖11-5顯示了垂直與水平分割面板,同時(shí)顯示在移動(dòng)分隔欄之前與之后的樣子。
11.2.1 創(chuàng)建JSplitPane
JSplitPane有五個(gè)構(gòu)造函數(shù)。通過這些構(gòu)造函數(shù),我們可以初始化所包含組件對(duì)的方向,設(shè)置continuousLayout屬性或是為容器初始化組件對(duì)。
public JSplitPane() JSplitPane splitPane = new JSplitPane(); public JSplitPane(int newOrientation) JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); public JSplitPane(int newOrientation, boolean newContinuousLayout) JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true); public JSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) JComponent topComponent = new JButton("Top Button"); JComponent bottomComponent = new JButton("Bottom Button"); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topComponent, bottomComponent); public JSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent) JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, topComponent, bottomComponent);
除非特別指定,默認(rèn)方向?yàn)樗椒较?。方向可以通過JSplitPane的常量VERTICAL_SPLIT或HORIZONTAL_SPLIT來指定。continuousLayout屬性設(shè)置瘊定了當(dāng)用戶拖動(dòng)分隔欄時(shí)分隔面板如何響應(yīng)。當(dāng)設(shè)置為false(默認(rèn))時(shí),在拖動(dòng)時(shí)只有分隔符被重繪。當(dāng)設(shè)置為true時(shí),在用戶拖拽分隔欄時(shí),JSplitPane會(huì)調(diào)整尺寸并重繪分隔欄每一邊的組件。
注意,如果方向?yàn)镴SplitPane.VERTICAL_SPLIT,我們可以將上部的組件看作左側(cè)組件,而將下部組件看作右側(cè)組件。
如果我們使用無參數(shù)的構(gòu)造函數(shù),分隔面板內(nèi)的初始組件集合由按鈕組成(兩個(gè)JButton組件)。其他的兩個(gè)構(gòu)造函數(shù)顯示的設(shè)置了初始的兩個(gè)組件。奇怪的是,其余的兩個(gè)構(gòu)造函數(shù)默認(rèn)情況下并沒有提供容器內(nèi)的組件。要添加或修改JSplitPane內(nèi)的組件,請(qǐng)參看稍后的“修改JSplitPane組件”一節(jié)。
11.2.2 JSplitPane屬性
表11-2顯示了JSplitPane的17個(gè)屬性。
設(shè)置方向
除了在構(gòu)造函數(shù)中初始化方向以外,我們可以通過將方向?qū)傩孕薷臑镴SplitPane.VERTICAL_SPLIT或是JSplitPane.HORIZONTAL_SPLIT來修改JSplitPane方向。如果我們?cè)囍鴮傩孕薷臑榉堑韧脑O(shè)置,則會(huì)拋出IllegalArgumentException。
不推薦在運(yùn)行時(shí)動(dòng)態(tài)修改方向,因?yàn)檫@會(huì)使用戶感到迷惑。然而,如果我們正在使用可視化開發(fā)工具,我們可以在創(chuàng)建JSplitPane之后顯示設(shè)置方向?qū)傩?。?dāng)沒有進(jìn)行可視化編程時(shí),我們通常在創(chuàng)建JSplitPane時(shí)初始化方向。
修改JSplitPane組件
有四個(gè)讀寫屬性可以用來處理JSplitPane內(nèi)組件的不同位置:bottomComponent, leftComponent, rightComponent與topComponent。事實(shí)上,這四個(gè)屬性表示兩種內(nèi)部組件:左邊與上部組件是一種;右邊與下部組件表示另一種。
我們應(yīng)該使用與我們的JSplitPane的方向相適應(yīng)的屬性。使用不合適的屬性方法會(huì)使得程序員的維護(hù)生命十分困難。想像一下,在創(chuàng)建用戶界面之后,在六個(gè)月之后看到如下的代碼:
JComponent leftButton = new JButton("Left"); JComponent rightButton = new JButton("Right"); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.setLeftComponent(leftButton); splitPane.setRightComponent(rightButton);
如果我們看一下代碼,基于變量名以及setXXXComponent()方法的使用,我們也許會(huì)認(rèn)為屏幕在左邊包含一個(gè)按鈕,而右邊也是一個(gè)按鈕。但是實(shí)例化的JSplitPane具有一個(gè)垂直方向,所創(chuàng)建的界面如圖11-6所示。所用的變量是按鈕的標(biāo)簽,而不是他們的位置。
如果setTopComponent()與setBottomComponent()方法使用更好的變量名,代碼會(huì)更容易理解:
JComponent topButton = new JButton("Left"); JComponent bottomButton = new JButton("Right"); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.setTopComponent(topButton); splitPane.setBottomComponent(bottomButton);
移動(dòng)JSplitPane分隔符
初始時(shí),分隔符顯示在上部組件的下面或是左邊組件的右邊合適尺寸處。任何時(shí)候,我們可以通過調(diào)用JSplitPane的restToPreferredSizes()方法來重新設(shè)置分隔位置。如果我們要編程來定位分隔符,我們可以通過setDividerLocation(newLocation)來修改dividerLocation屬性。這個(gè)屬性可以修改一個(gè)int位置,表示距離上部或左邊的絕對(duì)距離,或者是設(shè)置為一個(gè)0.0與1.0之間的double值,表示JSplitPane容器寬度的百分比。
注意,如果將屬性設(shè)置為0.0與1.0范圍之外的double值則會(huì)拋出IllegalArgumentException。
如果我們要設(shè)置分隔符的位置,我們必須等到組件已經(jīng)被實(shí)現(xiàn)。本質(zhì)上,這就意味著組件必須可見。有多種方法可以實(shí)現(xiàn)這一操作,最直接的方法就是向JSplitPane關(guān)聯(lián)一個(gè)HierarchyListener,并且監(jiān)聽HierarchyEvent何時(shí)變?yōu)镾HOWING_CHANGED類型。下面的代碼片段演示了這一操作,將分隔符位置修改為75%。
HierarchyListener hierarchyListener = new HierarchyListener() { public void hierarchyChanged(HierarchyEvent e) { long flags = e.getChangeFlags(); if ((flags & HierarchyEvent.SHOWING_CHANGED) == HierarchyEvent.SHOWING_CHANGED) { splitPane.setDividerLocation(.75); } } }; splitPane.addHierarchyListener(hierarchyListener);
盡管我們可以使用double值設(shè)置dividerLocation屬性,我們只會(huì)獲得了一個(gè)標(biāo)識(shí)絕對(duì)位置的int值。
調(diào)整組件尺寸與使用可擴(kuò)展的分隔符
對(duì)于JSplitPane內(nèi)的組件調(diào)整尺寸存在限制。JSplitPane會(huì)考慮到每一個(gè)所包含組件的最小尺寸。如果拖動(dòng)分隔符使得一個(gè)組件縮小到小于其最小尺寸,則滾動(dòng)面板不會(huì)允許用戶拖動(dòng)分隔符超過這個(gè)最小尺寸。
注意,我們可以編程實(shí)現(xiàn)將分隔符放在任意位置,甚至是使得組件小于其最小尺寸。然而這并不是一個(gè)好主意,因?yàn)榻M件最小尺寸的存在是有原因的。
如果組件的最小維度對(duì)于JSplitPane來說過大,我們需要修改組件的最小尺寸,從而分隔符可以使用組件的空間。對(duì)于AWT組件,修改一個(gè)標(biāo)準(zhǔn)組件的最小尺寸需要子類派生。對(duì)于Swing組件,我們可以簡單的通過一個(gè)新的Dimension來調(diào)用JComponent的setMinimumSize()方法。然而,最小尺寸的設(shè)置要合理。如果我們顯式的縮小其最小尺寸,組件就不會(huì)正常的工作。
有一個(gè)更好的方法可以使得一個(gè)組件比其他組件占用更多的空間:將JSplitPane的onTouchExpandable屬性設(shè)置為true。當(dāng)這個(gè)屬性為真時(shí),就會(huì)為分隔符添加一個(gè)圖標(biāo),從而使得用戶可以完全折疊起兩個(gè)組件中的一個(gè)來為另一個(gè)組件指定全部的空間。在圖11-7的盒子中,圖標(biāo)是一個(gè)上下箭頭的組合。
圖11-7顯示了這個(gè)圖標(biāo)顯示的樣子(通過Ocean觀感渲染)并且演示了在選擇分隔符上的向上箭頭來將下部的組件擴(kuò)展為其全部尺寸時(shí)的樣子。再一次點(diǎn)擊分隔符上的圖標(biāo)會(huì)使得組件又回到其先前的位置。點(diǎn)擊分隔符上圖標(biāo)以外的位置會(huì)將分隔符定位到使得折疊的組件位于其最優(yōu)尺寸處。
注意,并沒有較容易的方法來修改擴(kuò)展分隔符的圖標(biāo)或是修改分隔符如何渲染。這兩方面都是通過BasicSplitPaneDivider子類來定義并且在用于特定觀感類型的BasicSplitPaneUI子類的createDefaultDivider()方法中創(chuàng)建的。我們可以簡單修改分隔符周圍的邊框,這是一個(gè)自定義邊框。
lastDividerLocation屬性可以使得我們或是系統(tǒng)查詢前一個(gè)分隔符位置。當(dāng)用戶選擇maximizer圖標(biāo)來取消JSplitPane中的一個(gè)組件的最小化時(shí),JSplitPane會(huì)使用這個(gè)屬性。
小心,要小心其最小尺寸是基于容器尺寸或是其初始尺寸的組件。將這些屬性放置在JSplitPane中也許會(huì)要求我們手動(dòng)設(shè)置組件的minimum或是最優(yōu)尺寸。當(dāng)用在JSplitPane中時(shí)最常引起問題的組件就是JTextArea與JScrollPane。
調(diào)整JSplitPane尺寸
如果在JSplitPane中存在其所包含的組件的最優(yōu)尺寸所不需要的額外空間時(shí),這個(gè)空間會(huì)依據(jù)resizeWeight屬性設(shè)置進(jìn)行分配。這個(gè)屬性的初始設(shè)置為0.0,意味著右邊或是下邊的組件會(huì)獲得額外的空間。將這個(gè)設(shè)置修改為1.0會(huì)將所有的空間指定給左邊或上部的組件。0.5則會(huì)在兩個(gè)組件之間分隔面板。圖11-8顯示了這些變化的效果。
11.2.3 監(jiān)聽JSplitPane屬性變化
JSplitPane類定義了下列的常量來幫助監(jiān)聽邊界屬性的變化:
CONTINUOUS_LAYOUT_PROPERTY
DIVIDER_LOCATION_PROPERTY
DIVIDER_SIZE_PROPERTY
LAST_DIVIDER_LOCATION_PROPERTY
ONE_TOUCH_EXPANDABLE_PROPERTY
ORIENTATION_PROPERTY
RESIZE_WEIGHT_PROPERTY
監(jiān)聽用戶何時(shí)移動(dòng)分隔符的一個(gè)方法就是監(jiān)聽lastDividerLocation屬性的變化。列表11-2中的示例將一個(gè)PropertyChangeListener關(guān)聯(lián)到JSplitPane,從而顯示當(dāng)前的分隔符位置,當(dāng)前的最后位置以及前一個(gè)最后位置。分隔符上面與下面的組件是OvalPanel類(在第四章中討論),繪制來填充組件的維度。這個(gè)組件有助于演示將continuousLayout屬性設(shè)置true的效果狀態(tài)。
package swingstudy.ch21; import java.awt.BorderLayout; import java.awt.EventQueue; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JSplitPane; import swingstudy.ch04.OvalPanel; public class PropertySplit { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Runnable runner = new Runnable() { public void run() { JFrame frame = new JFrame("Property Split"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // create/configure split pane JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.setContinuousLayout(true); splitPane.setOneTouchExpandable(true); // create top component JComponent topComponent = new OvalPanel(); splitPane.setTopComponent(topComponent); // create bottom component JComponent bottomComponent = new OvalPanel(); splitPane.setBottomComponent(bottomComponent); // create PropertyChangeListener PropertyChangeListener propertyChangeListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { JSplitPane sourceSplitPane = (JSplitPane)event.getSource(); String propertyName = event.getPropertyName(); if(propertyName.equals(JSplitPane.LAST_DIVIDER_LOCATION_PROPERTY)){ int current = sourceSplitPane.getDividerLocation(); System.out.println("Current: "+current); Integer last = (Integer)event.getNewValue(); System.out.println("Last: "+last); Integer priorLast = (Integer)event.getOldValue(); System.out.println("Prior last: "+priorLast); } } }; // attach listener splitPane.addPropertyChangeListener(propertyChangeListener); frame.add(splitPane, BorderLayout.CENTER); frame.setSize(300, 150); frame.setVisible(true); } }; EventQueue.invokeLater(runner); } }
如下面的示例輸出所示,當(dāng)我們運(yùn)行前面的程序時(shí),我們會(huì)注意到lastDividerLocation屬性的變化來反映分隔符的拖動(dòng)。當(dāng)用戶停止拖動(dòng)分隔符時(shí),最后設(shè)置被設(shè)置為dividerLocation屬性的前一個(gè)設(shè)置,而不是用戶開始拖動(dòng)時(shí)的初始設(shè)置值。當(dāng)用戶拖動(dòng)分隔符時(shí),當(dāng)前值變?yōu)樽詈笠粋€(gè)值然后變?yōu)榍耙粋€(gè)最后值。
Current: 11 Last: -1 Prior last: 0 Current: 12 Last: 11 Prior last: -1 Current: 12 Last: 12 Prior last: 11 Current: 12 Last: 11 Prior last: 12 Current: 15 Last: 12 Prior last: 11 Current: 15 Last: 15 Prior last: 12 Current: 15 Last: 12 Prior last: 15 Current: 112 Last: 15 Prior last: 12 Current: 112 Last: 112 Prior last: 15 Current: 112 Last: 15 Prior last: 112
注意,PropertyChangeListener并不支持JSplitPane類的BOTTOM, DIVIDER, LEFT, RIGHT與TOP常量。相反,他們是為add(Component component, Object constraints)方法所用的內(nèi)部約束。
11.2.4 自定義JSplitPane類型
每一個(gè)可安裝的Swing觀感提供了不同的JSplitPane外觀以及組件的默認(rèn)UIResource值集合。圖11-9顯示了預(yù)安裝的觀感類型集合的JSplitPane容器外觀:Motif,Windows以及Ocean。
表11-3顯示了JSplitPane可用的UIResource相關(guān)的屬性集合。對(duì)于JSplitPane組件,有25個(gè)不同的屬性,包括3個(gè)分隔符特定的屬性。
關(guān)于Java圖形界面開發(fā)中的高級(jí)Swing容器怎么用就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。