導航:首頁 > 知識科普 > setlayout有哪些方法

setlayout有哪些方法

發布時間:2023-05-10 05:27:17

㈠ java有什麼方法可以把組件放到JPanel的指定位置

可以用 setBounds(x,y,w,h); 組閉激件左上角x,y,寬高w,h
假定你悔態激窗體寬高為:400,300,左部面板p,按鈕btn1,2,3,4
jf.setLayout(null);//父容器碧襪布局要為null
p.setLayout(new GridLayout(4,4));//左邊面板4*4網格

p.setBounds(0,0,300,240);
btn1.setBounds(245,10,50,40);
btn2.setBounds(245,80,50,40);
btn3.setBounds(245,150,50,40);
btn4.setBounds(245,220,50,40);
位置不合適,可以慢慢調

㈡ 以下哪些方法可以設定組件參數

可以設置setlayout(null); 然後再在用setbounds(X,Y,width,height)是設置一個組件的位置和大小,4個參數用來確定一個長方形的區域,前兩個分別沖兆是飢清矩形散肢租左上角點的橫縱坐標,後面兩個參數是寬和高。

㈢ UGUI Layout

一、 UGUI布局系統由 布局元素 (Layout Elements)和 布局控制器 (Layout Controller)組成。

1、布局控制器的基礎介面為ILayoutController。

(1)ILayoutController有兩個方法,布局系統調用這兩個方法的順序是固定的,首先調用SetLayoutHorizontal,再調用SetLayoutVertical:

A、void SetLayoutHorizontal() :處理水平方向的布局;

B、void SetLayoutVertical() :處理垂直方向的布局。

(2)繼承ILayoutController的兩個介面:

A、ILayoutSelfController :只控制自己RectTransform的改變坦好;繼承ILayoutSelfController的兩個類如下:

[1] (內容尺寸適配器) Content Size Fitter  <—— ILayoutSelfController:根據孩子中布局元素的尺寸及自身包含內容的多少控制自身的尺寸;

[2] (縱橫比適配器) AspectRatioFitter  <—— ILayoutSelfController:根據自身設置的模式(AspectMode)和比率(Aspect Ratio)以及寬或高調整另一邊的大小,不受局彎子元素的影響。

B、ILayoutGroup :控制所有孩子節點的布局變化。這個介面就是我們比較熟悉的介面,平時項目中使用的很多布局組件都繼承該介面:

[1] ScrollRect   <—— ILayoutGroup;

[2] GridLayoutGroup   <—— LayoutGroup  <—— ILayoutGroup;

[3] HorizontalLayoutGroup\VerticalLayoutGroup->  <—— LayoutGroup <—— ILayoutGroup

2、所有包含RectTransform組件的GameObject都視為布局元素。

(1)布局元素擁有一些定義自身尺寸的屬性:

A、Minimum width:最小寬度;

B、Minimum height:最小高度;

C、Preferred width:如果有充足的空間可以分配的最合適寬度;

D、Preferred height:如果有充足的空間可以分配的最合適高度;

E、Flexible width:靈活寬度,一般是相對於父元素的比例;

F、Flexible height:靈活高度,一般是相對於父元素的比例。

默認情況下,Minimum width、Minimum height、Preferred width、Preferred height均為0,Flexible width、Flexible height都是disabled的。如果想調整這些屬性就需要添加繼承ILayoutElement介面的組件重寫這些值。像我們常用的Text、Image組件桐信悶都繼承了ILayoutElement;同時一些布局控制器自身也繼承了ILayoutElement,如:LayoutGroup(包括所有繼承LayoutGroup的子類)、ScrollRect;UISystem也創建了一個單獨組件LayoutElement繼承ILayoutElement,任何一個想重寫上述屬性的GameObject都可以通過添加LayoutElement組件實現。LayoutElement同時繼承了ILayoutIgnorer介面,可以通過設置ignoreLayout決定該GameObject是否被Layout System忽略。

(2)ILayoutElement定義了布局元素用到的屬性minWidth、preferredWidth、flexibleWidth、minHeight、preferredHeight、flexibleHeight,

同時定義了兩個方法:

void ():計算布局元素的minWidth,preferredWidth和flexibleWidth值

void CalculateLayoutInputVertical():計算布局元素的minHeight,preferredHeight和flexibleHeight值

二、布局重建過程

1、首先引起布局重建的元素調用LayoutRebuilder.MarkLayoutForRebuild() ,然後逐層向上遞歸查找直到找到最上層的布局根節點,這個根節點必須包含繼承ILayoutGroup介面、Behaviour類並且isActiveAndEnabled屬性為true的組件。然後以這個根節點初始化一個布局重建器LayoutRebuilder,然後將該LayoutRebuilder添加到CanvasUpdateRegistry中m_LayoutRebuildQueue隊列中等待處理。調用過程如下:

static void LayoutRebuilder.MarkLayoutForRebuild(RectTransform rect) 

->static void LayoutRebuilder.MarkLayoutRootForRebuild(RectTransform controller) 

->static bool CanvasUpdateRegistry.(ICanvasElement element) 

-> CanvasUpdateRegistry.(ICanvasElement element) 

-> 加入m_LayoutRebuildQueue隊列中。

其中有一個比較特殊的就是ScrollRect,在ScrollRect的OnEnable()方法和SetDirtyCaching()方法中會先調用CanvasUpdateRegistry.(this),再調用LayoutRebuilder.MarkLayoutForRebuild(rectTransform)。與LayoutRebuilder比較,ScrollRect本身也繼承了ICanvasElement介面。在Rebuild()函數中,ScrollRect針對CanvasUpdate.Prelayout(布局執行前)和CanvasUpdate.PostLayout(布局執行後)兩個階段實現了自己的執行邏輯。而LayoutRebuilder的Rebuild()函數只針對CanvasUpdate.Layout階段實現對應的執行邏輯

2、CanvasUpdateRegistry構造函數中會將PeformUpdate方法加入Canvas.willRenderCanvases事件中,然後在渲染所有的Canvas之前,拋出willRenderCanvases事件從而調用PeformUpdate(),在PeformUpdate函數中執行步驟如下:

(1)首先會刪除m_LayoutRebuildQueue中所有無效的元素;

(2)然後根據節點的深度(父節點個數越大越靠前)對m_LayoutRebuildQueue排序;

(3)然後分別以CanvasUpdate.PreLayout(布局前),CanvasUpdate.Layout(布局),CanvasUpdate.PostLayout(布局後)的參數順序調用每一個ICanvasElement元素的Rebuild方法;

(4)然後調用所有ICanvasElement元素的LayoutComplete()方法。針對該方法只有LayoutRebuilder類中實現:將該LayoutRebuilder從LayoutRebuilder的靜態對象池s_Rebuilders中刪除;

(5)然後清空m_LayoutRebuildQueue隊列;

(6)布局結束後調用ClipperRegistry.instance.Cull()遍歷所有裁剪組件(繼承IClipper介面的組件,如RectMask2D)的裁剪方法PerformClipping()。 

3、下面看一下ICanvasElement布局重建過程的實現,重建的實現就在LayoutRebuilder的Rebuild方法中,源碼如下:

如上所示,整個布局分四個步驟:

(1)對該節點下所有有效(繼承Behaviour且isActiveAndEnabled為true)的布局元素(即包含繼承ILayoutElement組件的節點)執行()計算水平方向布局尺寸。對孩子的遍歷順序由下往上,因為父節點尺寸計算依賴於子節點的尺寸;雖然針對所有布局元素,但是真正實現()方法的只有LayoutGroup相關的組件。

LayoutGroup實現了一個虛方法(),主要就是收集其子節點下所有沒有被標記 ignoreLayout 的物體存到m_RectChildren列表中。LayoutGroup的子類重寫該函數時都會先調用這個虛函數,然後再執行自己特有的邏輯。

A、 水平布局組件 HorizontalLayoutGroup <—— <—— LayoutGroup

重寫()。如上,首先調用LayoutGroup中()方法,然後調用中的CalcAlongAxis(int axis, bool isVertical)方法,CalcAlongAxis()是一個公用方法,可以根據傳入的參數確定計算哪個方向的尺寸,其中axis表示方向(0:horizontal 1:vertical),isVertical判斷是否一個Vertical Group。CalcAlongAxis()執行過程如下:

① 首先遍歷所有孩子節點調用GetChildSizes()方法獲取對應方向上的尺寸(min、preferred、flexible);

② 然後根據所有子節點的尺寸計算當前節點對應方向上的尺寸totalMin、totalPreferred、totalFlexible;

③ 調用SetLayoutInputForAxis()方法將第二步計算的值設置對應的向量m_TotalMinSize、m_TotalPreferredSize、m_TotalFlexibleSize;

B、垂直布局組件VerticalLayoutGroup 重寫方法如下,實現參考

(2)對該節點下所有布局控制器(即包含繼承ILayoutController組件的節點)執行SetLayoutHorizontal()設置水平布局。對孩子的遍歷順序自上而下,因為孩子節點實際的布局依賴於父節點的布局;

A、HorizontalLayoutGroup和VerticalLayoutGroup中的SetLayoutHorizontal()會直接調用.SetChildrenAlongAxis()方法根據布局方向和布局組件類型設置其下子布局元素的位置和尺寸。

B、GridLayoutGroup也重寫了SetLayoutHorizontal()方法,直接調用SetCellsAlongAxis(0),針對水平布局實現如圖2-4所示,只設置每個子元素的尺寸,而不會改變子元素的位置。

(3)對該節點下所有布局元素(即包含繼承ILayoutElement組件的節點)執行()計算垂直方向布局尺寸;對孩子的遍歷順序由下往上;

(4)對該節點下所有布局控制器(即包含繼承ILayoutController組件的節點)執行SetLayoutVertical()設置垂直布局。對孩子的遍歷順序自上而下;

從上面的執行順序還可以看出,Layout System先搞定水平方向的布局然後才去設置垂直方向的布局。

三、布局重建觸發因素

1、 以下函數,都會直接或間接的調用LayoutBuilder.MarkLayoutForRebuild()觸發布局重建:

(1)OnEnable() :所有繼承ILayoutController或ILayoutElement組件(AspectRatioFitter除外)的OnEnable()方法都會都會間接調用LayoutBuilder.MarkLayoutForRebuild();

A、Graphic :OnEnable() -> SetAllDirty() -> ( m_SkipLayoutUpdate變數為false時才會調用 )LayoutBuilder.MarkLayoutForRebuild();

B、LayoutGroup\ContentSizeFitter\LayoutElement\ScrollRect :OnEnable() -> SetDirty() -> LayoutBuilder.MarkLayoutForRebuild()。

(2)OnDisable() :所有繼承ILayoutController或ILayoutElement組件的OnDisable()方法都會調用LayoutBuilder.MarkLayoutForRebuild()

(3)(): RectTransform尺寸變化時調用。繼承自UIBehaviour的ContentSizeFitter、LayoutGroup、ScrollRect、Graphic都重寫了該方法,具體調用如下:

A、ContentSizeFitter :() ->SetDirty() -> (IsActive()為true才會調用)LayoutRebuilder.MarkLayoutForRebuild();

B、LayoutGroup :() ->(isRootLayoutGroup為true時才會調用)SetDirty() ->(IsActive()為true時才會調用)LayoutRebuilder.MarkLayoutForRebuild();

C、ScrollRect :() -> SetDirty() ->( IsActive()為true時才會調用 )LayoutRebuilder.MarkLayoutForRebuild();

D、Graphic :() ->( gameObject.activeInHierarchy為true時才會調用 )SetLayoutDirty() ->(IsActive()為true時才會調用)LayoutRebuilder.MarkLayoutForRebuild();

(4)OnDidApplyAnimationProperties(): 動畫導致屬性( 重寫OnDidApplyAnimationProperties()方法的類自身所特有的屬性 )改變時調用。繼承UIBehaviour的Graphic、LayoutGroup、LayoutElement都重寫了該方法,具體調用如下:

A、Graphic :OnDidApplyAnimationProperties() -> SetAllDirty() -> ( m_SkipLayoutUpdate變數為false時才會調用 )LayoutBuilder.MarkLayoutForRebuild()。Graphic本身是個抽象類,不能當作組件直接添加,而繼承自Graphic的Image\Text( ——> MaskableGraphic  ——> Graphic)組件的一些特有屬性,如圖3-1紅框內標記,當動畫改變Text的這些屬性時會調用OnDidApplyAnimationProperties()函數。如圖3-2紅框內標記,當動畫改變Image的這些屬性時會調用OnDidApplyAnimationProperties()函數。

B、LayoutGroup :OnDidApplyAnimationProperties() -> SetDirty() -> ( IsActive()為true時才會調用 )LayoutBuilder.MarkLayoutForRebuild()

如圖3-3、3-4、3-5分別是VerticalLayoutGroup、HorizontalLayoutGroup,當動畫改變VerticalLayoutGroup的這些屬性時會調用OnDidApplyAnimationProperties()函數。

C、LayoutElement :OnDidApplyAnimationProperties() -> SetDirty() -> ( IsActive()為true時才會調用 )LayoutBuilder.MarkLayoutForRebuild()

如圖3-6所示,當動畫改變LayoutElement的這些屬性時會調用OnDidApplyAnimationProperties()函數。

(5)() :父節點transform屬性變化前調用。繼承自UIBehaviour的Graphic和LayoutElement類都重寫了該方法:

A、Graphic :() -> SetAllDirty() -> LayoutBuilder.MarkLayoutForRebuild()

B、LayoutElement :() -> SetDirty() -> LayoutBuilder.MarkLayoutForRebuild()

2、 某些組件特有屬性變化或函數調用:

(1)RectTransform 中導致布局變化的屬性:Width、Height、Scale、以及錨點變化;

(2)Text 中導致布局變化的屬性:text、alignment、fontSize、horizontalOverflow、verticalOverflow、lineSpacing、fontStyle、resizeTextForBestFit、resizeTextMinSize、supportRichText、resizeTextMaxSize、font;方法:FontTextureChanged()。

(3)Image 中導致布局變化的屬性:sprite、overrideSprite;方法:SetNativeSize()、OnCanvasHierarchyChanged()。其中OnCanvasHierarchyChanged()只有在canvas.referencePixelsPerUnit變化且Image類型為Sliced或Tiled時才會調用SetLayoutDirty()

(4)LayoutGroup 中導致布局變化的屬性:padding、childAlignment;方法:OnTransformChildrenChanged()

(5)GridLayoutGroup 中導致布局變化的屬性:startCorner、startAxis、cellSize、spacing、constraint、constraintCount

(6) 中導致布局變化的屬性:spacing、childForceExpandWidth、childForceExpandHeight、childControlWidth、childControlHeight、childScaleWidth、childScaleHeight

(7)ContentSizeFitter 中導致布局變化的屬性:horizontalFit、verticalFit

(8)LayoutElement 中導致布局變化的屬性:ignoreLayout、minWidth、minHeight、preferredWidth、preferredHeight、flexibleWidth、flexibleHeight、layoutPriority

(9)ScrollRect 中導致布局變化的屬性:verticalScrollbar、horizontalScrollbar、horizontalScrollbarVisibility、verticalScrollbarVisibility、viewport

四、布局重建分析工具

1、第三節我們總結了一些可能導致布局重建的原因,游戲中盡量避免執行這些操作以減少布局重建,同時盡可能少的使用Layout相關組件以減少CPU時間的佔用。通過第二節對重建過程的分析,我們知道每個引起布局重建的元素的元素都會先加入CanvasUpdateRegistry中m_LayoutRebuildQueue隊列中,所以我們可以通過反射的方式來獲取游戲中引起布局重建的元素(引用 https://www.xuanyusong.com/archives/4573),腳本如下:

public class CheckRebuildElement:MonoBehaviour

{

       IList m_LayoutRebuildQueue;

        privatevoid Awake()

        {

           System.Type type = typeof(CanvasUpdateRegistry);

           FieldInfo field = type.GetField("m_LayoutRebuildQueue",BindingFlags.NonPublic | BindingFlags.Instance);

           m_LayoutRebuildQueue = (IList)field.GetValue(CanvasUpdateRegistry.instance);

        }

        privatevoid Update()

        {

            for(int j = 0; j < m_LayoutRebuildQueue.Count; j++)

            {

                varrebuild = m_LayoutRebuildQueue[j];

                if(ObjectValidForUpdate(rebuild))

                {

                    if(rebuild.transform)

                   {

                       Debug.LogFormat("{0} 引起布局重建", rebuild.transform.name);

                       Graphic g = rebuild.transform.GetComponent();

                       if ((g != null) && (g.canvas != null))

                       {

                           Debug.LogFormat(" 網格:{0}",rebuild.transform.GetComponent().canvas.name);

                       }

                   }                                      

                }

            }

        }

        privatebool ObjectValidForUpdate(ICanvasElement element)

        {

            var valid = element != null;

            var isUnityObject = element is UnityEngine.Object;

            if(isUnityObject)

               valid = (element as UnityEngine.Object) != null; //Here we make use ofthe overloaded UnityEngine.Object == null, that checks if the native object isalive.

            return valid;

        }

}

㈣ JAVA求大神

6.選擇A,因為知行皮外層循環是0-3就是4次,內層循環是搭差0-2三次,所以乘起來就是帶吵12次
7.C setLayout方法是設置布局的
8.B getSelectedItem是一個內置方法,獲取選中的下拉的值
9.B West是西,上北下南,左西右東

㈤ Java:Applet布局問題

applet布局問題

按鈕 標簽是怎樣加入到applet程序(容器)當中去的呢?

需要用到布局容器管理器(LayoutManager) 它用於協助容器確定加入的組件(按鈕等)應該放置的位置

awt提供了 中常用的布局容器管理器

>>FlowLayout

>>BorderLayout

>>GridLayout

>>CardLayout

applet默認使用FlowLayout applet使用容器管理器的方法如下

setLayout (new BorderLayout)

setLayout()方法是applet類繼承Container類中的方芹高法而來 因此在applet程序中可以直接調用

applet加入按鈕一定需要上面的容器管理器么?

不一定 可以先 setLayout(null); 然後自己確定組件放置的細節 代碼麻煩

如果你不用布局管理器(Jframe中的用法)

JButton b = new JButton( hello );

getContentPane() add(b );

b setLocation( );

以下是容器管理器常用的 種布局寫法

=================================================

applet 使用 FlowLayout 布局

指定布局:setLayout(new FlowLayout())

加入組件 add(組件實例)

作用 由左到右 由上到下依次放置組件

加入組件使用applet類繼承Container類中的方法成員add();

=================================================

import java awt *;

import java applet *;

public class UseFlowLayout extends Applet{

public void init()

{

setLayout(new FlowLayout()); //因為是默認管理器 可以省略

//setLayout()方法是applet類繼承Container類中的方法而來 因此在applet程序中可以直接調用

for(int i = ; i< ;i++){

add(new Button( 按鈕 + i )); //加入 個按鈕

//applet類繼承Container類中的方法成員add();

}

}

}

==================================================

applet使用BorderLayout();

指定布局 setLayout(new BorderLayout());

加入組件 add(組件實例 位置常量)

作用 此種布局將容器劃分為 個區域 分別是上 下 左 右 中

[位置常量]指定了組件將要放置的位置

如果組件不足 個 放隱首猛在中間位置的組件將自動填充空餘位置

==================================================

import java awt *;

import java applet *;

public class UseBorderLayout extends Applet{ //介面Applet

public void init()

{

setLayout(new BorderLayout()); //因為是默認管理器 可以省略

add(new Button( 按鈕上 ) BorderLayout NORTH);

add(new Button( 按鈕右 ) BorderLayout EAST);

//?setHgap( );想設置組件的水平和垂直的邊距 看下面的GridLayout使用方法

灶橋add(new Button( 按鈕中 ) BorderLayout CENTER);

//add(new Button( 按鈕下 ) BorderLayout SOUTH) //引上是為了測試自動填充效果

//add(new Button( 按鈕左 ) BorderLayout WEST) //引上是為了測試自動填充效果

}

}

==================================================

applet使用GridLayout();

指定布局 setLayout(new GridLayout(列數 行數))

加入組件 add(組件實例)

作用 左 >右 上 >下 分成指定的網格

==================================================

import java awt *;

import java applet *;

public class UseGridLayout extends Applet{ //介面Applet

public void init()

{

//setLayout(new GridLayout( )); //書上的寫法 我的寫法如下

//聲明一個布局管理器 為表格形式 行 列

GridLayout GL = new GridLayout( );

GL setHgap( ); //設置組件的水平和垂直的邊距

GL setVgap( );

this setLayout(GL); //是哪個類對象的方法?!是this:當前applet

//加入按鈕

for(int i= ;i< ;i++)

{

this add(new Button( 按鈕 + i)) ;

//add方法是哪個類對象的?!也是當前面板的方法

}

}

}

=========================================================

+applet使用 CardLayout容器管理器

指定容器管理器 setLayout(new CardLayout())

加入組件 add(組件實例 指定組件名稱 )

顯示組件 CL show(this button ) next previous first

作用 組件加入容器applet中 然後按照需要調出 被調出的組件遮蓋本容器內的所有組件

注意 applet是容器 但不是唯一的 applet還可以加入多個容器!詳細內容明天再學

=========================================================

import java awt *;

import java applet *;

public class UseCardLayout extends Applet{ //介面Applet

public void init()

{

//指定當前applet布局管理器為CardLayout

CardLayout CL = new CardLayout();

setLayout(CL);

//加入按鈕

for(int i= ;i< ;i++)

{

add(new Button( 按鈕 + i) button + i) ;

}

CL show(this button ); //將指定按鈕顯示出來

CL next(this); //轉到下一個按鈕 這里說明循環顯示的效果 顯示出是button ;

//還有CL first(this)等方法==如 last previous next first 顯示指定的就用上面的方法

}

}

以上是applet作為容器 需要用到的最常用的組件布局辦法

實際上一個容器還可以使用多個LayoutManager

用Panel!

Panel屬於awt組件的容器類 也就是說它可以用來放置其他的awt組件

她的重要特點就是 擁有獨立的坐標系統和layoutmanager

Panel 與 LayoutManager結合可以做出更符合需要的applet界面!

附applet測試頁面

<!DOCTYPE HTML PUBLIC //W C//DTD HTML Transitional//EN >

<HTML>

<HEAD>

<TITLE> New Document </TITLE>

<META NAME= Generator CONTENT= EditPlus >

<META NAME= Author CONTENT= >

<META NAME= Keywords CONTENT= >

<META NAME= Description CONTENT= >

</HEAD>

<BODY>

<applet code= UseBorderLayout class width= height= ></applet>

</BODY>

</HTML>

lishixin/Article/program/Java/hx/201311/26137

㈥ setLayout()方法的問題

是Container
是指容器櫻茄培布局納螞模脊唯式

FlowLayout
BorderLayout
GridLayout
等等

㈦ setLayout()方法的類是哪個

setLayout()是繼承穗前JFrame 而來的。你得猜做清把你的類繼承它就可以調用了。給個簡單的案例:

import java.awt.FlowLayout;
import javax.swing.JFrame;
public class MyFrame extends JFrame {
//重寫構造方法
MyFrame(){
this.setLayout(new FlowLayout());//設置布局為流布局
this.setBounds(100, 50, 400, 400);//設置窗體出現的位置和大小
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設置點擊關閉按鈕時的動作
this.setVisible(true);//設置窗胡譽體可見
}

public static void main(String[] args) {
new MyFrame(); //調用方法進行測試

}
}

㈧ 總結幾種常用的GUI布局

(2)使用指定的布局方式:創建指定布局方式類的對象,然後調用容器類的setLayout()方法來指定所需的布局方式。例:setLayout(new FlowLayout());ps:一般Java中默認採用相對定位布局,如需要使用絕對定位布局,則應該取消容器的布局方式(setLayout(null)),然後使用 setLocation() setSize() setBounds()設置組件的大小及位置。(3)下面分別對幾種布局方式的編程加判段以說明。先說課本上出現的:1、Flowlayout默認為從上到下從左到右依次擺放,每行均居中,自動換行,也可設置對齊方式,它是Panel、Applet的預設布局。 組件順序和尺寸不隨窗口變化而變化。 2、BorderLayout將容器內的空間劃分為東、南、西、北、中五個方位,並指明組件所在的方位,掘碼譽它是Window、Dialog、Frame的預設布局方式。 north與south有確定的高度,west與east有確定的寬度。 3、GridLayout行列網格狀布局。這種布局方式首先放一個容納單元的柵格,元件放到這個網格的單元個中,GridLayout構造方法: GridLayout(int row,int col)GridLayout(int row,int col,int hGap,int vGap) 其中:row:行數 col: 列數 如果某個值為零,表示這個方向可以任意擴展。 HGap、vGap表示以象素為單位的元件間隔。 元件總是充滿單元格,而且隨著邊框的變化而變化。 補充幾個課外的:4、CardLayout卡片疊式布局。這種布局方式,可以用來管理兩個或者更多共享同一顯示區域的元件。它具有以下兩個構造方法: CardLayout()CardLayout(int hGap,int vGap) 樣例: package demo; import java.awt.*;import java.awt.event.*;import java.*;import java.lang.*; public class GuiDemo extends Frame { //構造一個容器,放置可變的元件 Panel cardContainer=new Panel(); //構造函數的參數為長度 TextField jTextField1 = new TextField(30); Button jButton1 = new Button(); Button jButton2 = new Button(); Button jButton3 = new Button(); //列表框 Choice c=new Choice(); String ca1="按鈕"; String ca2="正文域"; //構造函數 public GuiDemo() { jbInit(); } //開始代碼 public static void main(String[] args) { GuiDemo frame = new GuiDemo(); //顯示元件 frame.setVisible(true); } //初始化代碼,這里踢出了錯誤 private void jbInit() { //激活Windows事件 enableEvents(AWTEvent.WINDOW_EVENT_MASK); //模培設置窗口的標題,大小與布局 setTitle("元件加入的程序演示"); setSize(new Dimension(300, 200)); //所有的元件都按順序方式布局 this.setLayout(new BorderLayout(0,3)); jTextField1.setText("您好"); jButton1.setLabel("按鈕1-1"); jButton2.setLabel("按鈕1-2"); jButton3.setLabel("按鈕1-3"); //列表框賦初值 c.add(ca1); c.add(ca2); //構造下拉列表改變的事件偵聽器 c.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(ItemEvent e) {myItem(e);} } ); //構造一個容器放列表框 Panel globarPanel=new Panel(); globarPanel.add(c); this.add("North",globarPanel); //cardContainer按CardLayout布局 cardContainer.setLayout(new CardLayout()); Panel p1=new Panel(); p1.add(jButton1); p1.add(jButton2); p1.add(jButton3); Panel p2=new Panel(); p2.add(jTextField1); //把兩個容器都加入 cardContainer.add(ca1,p1); cardContainer.add(ca2,p2); this.add("Center",cardContainer); } //這是下拉列表改變的事件程序 void myItem(ItemEvent e) { ((CardLayout)cardContainer.getLayout()).show( cardContainer,(String)e.getItem()); } //這是檢測退出程序的的事件,沒有這個事件窗口將無法關閉 protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0); } }} 5、GridBayLayout自定義網格狀布局。 看起來有很多約束需要進行設置,但事實上許多約束只需設置一次,並對多個組件重用,每次添加組件時只有少數的項需要修改.常用構造: public GridBagLayout() 樣例: package demo; import java.awt.*;import java.awt.event.*;import java.*;import java.lang.*; public class GuiDemo extends Frame { //構造函數 public GuiDemo() { jbInit(); } //開始代碼 public static void main(String[] args) { GuiDemo frame = new GuiDemo(); frame.setTitle("元件加入的程序演示"); frame.setSize(300,200); //顯示元件 frame.setVisible(true); } public void makebutton( String name, GridBagLayout gridbag, GridBagConstraints c) { Button button=new Button(name); gridbag.setConstraints(button,c); this.add(button); } //初始化代碼 private void jbInit() { //激活Windows事件 enableEvents(AWTEvent.WINDOW_EVENT_MASK); GridBagLayout gridbag=new GridBagLayout(); GridBagConstraints c=new GridBagConstraints(); this.setFont(new Font("宋體",Font.PLAIN,11)); this.setLayout(gridbag); c.fill=GridBagConstraints.BOTH; c.weightx=1.0; makebutton("Bt1",gridbag,c); makebutton("Bt2",gridbag,c); makebutton("Bt3",gridbag,c); c.gridwidth=GridBagConstraints.REMAINDER; makebutton("Bt4",gridbag,c); c.weightx=0.0; makebutton("Bt5",gridbag,c); c.gridwidth=GridBagConstraints.RELATIVE; makebutton("Bt6",gridbag,c); c.gridwidth=GridBagConstraints.REMAINDER; makebutton("Bt7",gridbag,c); c.gridwidth=1; c.gridheight=2; c.weighty=1.0; makebutton("Bt8",gridbag,c); c.weighty=0.0; c.gridwidth=GridBagConstraints.REMAINDER; c.gridheight=1; makebutton("Bt9",gridbag,c); makebutton("Bt10",gridbag,c); } //這是檢測退出程序的的事件,沒有這個事件窗口將無法關閉 protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0); } }} (凌霄)

㈨ 簡述java程序設計中界面設計中的三種布局方式

1 邊框布局

JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
憑著我們現在所積累的閱讀程序的功夫,應該能夠很快地知道我們通過第一條語句創建了一個容器JPanel類的panel1。
而接下來,我們則調用了panel1.setLayout(new FlowLayout()),在上一章中,我們一直沒有對它進行相應的分析。現在該是揭開它的面紗的時候了。
單詞layout的中文意思是「布局」、「布置」,setLayout就是設置布局格式。也就是說,容器panel1的方法setLayout是用來設置布局格式的。那麼,我們一直用的是什麼模式呢?對,就是後面括弧里的FlowLayout()。顧名思義,也就是流布局方式。這是一種順其自然的方式:從左到右,一個個對象地擺放,擺不下,就擺到下一行。所以,我們就無法去控制它。
從本章開始,我們就要學習一種控制布局的方法。在Java語言中,提供了各種布局管理器,以便大家能夠達頌此到這一目的。
通常我們最常使用的布局管理器是:Border Layout(邊框布局管理器),如下圖所示,邊框布局管理器將一個屏幕分成了五個部分:東、南、西、北、激簡中。

如果要使用這種邊框布局管理進行布局控制,我們必須先將「容器」設置為「邊框布局控制模式」,具體來說,就是當調用setLayout方法為容器設置布局控制模式時,參數設置為BorderLayout。例如:
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new BorderLayout());
然後,我們就可以在使用容器的add方法添加部件時,附加上位置參數,使得該部件顯示在指定的位置上。位置參數分別是:
BorderLayout.NORTH 位置為北
BorderLayout.SOUTH 位置為南
BorderLayout.EAST 位置為東
BorderLayout.WEST 位置為西
BorderLayout.NORTH 位置為中心

實例說明

下面,我們就來試一試,使用按鈕排出五個方向!請創建一個testBorder.java,輸入以下源程序:
源程序:useTextArea.java
import java.awt.*;
import javax.swing.*;
import java.applet.Applet;

public class testBorder extends JApplet
{
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new BorderLayout());

JButton north=new JButton("North");
JButton south=new JButton("South");
JButton east=new JButton("East");
JButton west=new JButton("West");
JButton center=new JButton("Center");

panel1.add(north,BorderLayout.NORTH);
panel1.add(south,BorderLayout.SOUTH);
panel1.add(east,BorderLayout.EAST);
panel1.add(west,BorderLayout.WEST);
panel1.add(center,BorderLayout.CENTER);
}
}

然後,我們使用javac編譯這個程序,然後編輯一個顯示這個Java Applet的HTML頁面。最後調用appletviewer來觀察這個頁面

為了試一下,如果並沒有在每個位置都安排一個部件,那麼會怎麼樣呢?我們修改一下程序,將panel1.add(west,BorderLayout.WEST);這一行注釋掉(就是在前面加上「//」號),也就是不顯示西邊的按鈕,看一下結果如何。正如上圖(圖10-3)所示,西邊由於沒有部件,因此「中」就朝西靠,「佔領」了它的位置。

而如果我們修改一下程序,讓中間的按鈕不顯示的話,就會出現如圖10-5的樣子,中間的區域並未並佔領,而是明櫻褲空在那裡了!這是與其它位置不同的地方,大家一定要記住。

一些提示:
其實這很好理解,如果中間的那一塊的位置被其它位置上的部件佔領的話,就會使得分不清「東」、「南」、「西」、「北」了。倒成了「左上角」、「左下角」、「右上角」、「右下角」了。

2 網格布局
實例說明

下面,我們來看一個新的程序!首先創建一個testGrid.java文件,並輸入以下源程序:
源程序:testGrid.java

import java.awt.*;
import javax.swing.*;
import java.applet.Applet;

public class testGrid extends JApplet
{
String buttonLabels[]={"No.1","No.2","No.3","No.4","No.5",
"No.6","No.7","No.8","No.9"};

public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(3,3));

for (int x=0; xpanel1.add(new JButton(buttonLabels[x]));
}
}

然後,我們使用javac編譯這個程序,然後編輯一個顯示這個Java Applet的HTML頁面。最後調用appletviewer來觀察這個頁面

我們主要是關心如何擺放各個部件,而不是如何構建一個程序。所以,正如本例中的按鈕一下,這一章中的所有部件都是一個樣子,沒有任何作用。這樣也使得程序盡可能地變短了,更易於大家閱讀和理解程序。
下面,我們就一起來看一下上面的這個程序。
1) String buttonLabels[]={"No.1","No.2","No.3","No.4","No.5",
"No.6","No.7","No.8","No.9"}
我想大家都能很輕松地讀懂這條語句,我們在此定義了一個字元串數組buttonLabels,它有9個字元串成員,也就是我們後面定義的9個按鈕的標簽文本。
值得注意的是,大家一定要知道,buttonLabels[1]表示哪個字元串!如果您的答案是「No.1」的話,就錯了!正確的答案是「No.2」,這是因為在數組中索引值是從0開始的,也就是說如果要使用「No.1」的話,應該使用buttonLabels[0]。這對更好地理解後面的程序十分重要,也是基本功之一。
2) JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(3,3));
在這兩行程序中,我們首先定義了一個容器部件panel1。然後調用setLayout方法設置布局管理器。這里我們使用了一個新的布局管理器:GridLayout,網格布局管理器。
我們注意到GridLayout的後面帶了兩個參數:3,3。這有什麼用呢?我們一起來看一下GridLayout方法的定義:
public GridLayout (int rows,int cols)
我們看一下這兩個參數,首先它們都是int型—整型的。那麼它們分別起到什麼作用呢?我們還是採用顧名思義法吧!row的中文意思是行,col的中文意思是列,後面加上一個s,是這兩個單詞的復數形式。
好,我們現在串起來想一下,我們定義了一個網格布局,然後定了它的行、列數!這不就畫出了這個網格了嗎?如果我們在語句是使用GridLayout(5,5)的話,就會把整個容器分成25個單元
而我們在程序中使用的是GridLayout(3,3),所以它就將整個容器分成了

注意:
這種劃分是一種邏輯上的,暗藏式的劃分,而不會把格子給劃出來。另外,我們這里舉的兩個例子行、列都相等,其實完全可以不等。

3) for (int x=0; xpanel1.add(new JButton(buttonLabels[x]));
這是一個循環結構的程序。我們先看循環語句,循環的初值是「x=0」,繼續執行循環的條件語句是「xbuttonLabels.length就是用來請得字元串數組buttonLabels的長度!也就是這個字元串數組中有多少個字元串?我們知道,我們在該數組中定義了9個。
從程序中,我們可以獲知,當x=buttonLabels.length時,循環就將結束,應為它不滿足條件x別忘了,我們使用buttonLabels[0]表示第一個字元串,buttonLabels[1]表示第二個字元串……,那麼最後一個字元串就應該是buttonLabels[buttonLabels.length-1]嘛。
在循環中,我們使用容器提供的add方法,將新定義的按鈕部件添加進去。
有時,我們可能想獲得象下圖所示的布局效果!讓各個部件之間存在一些間隙。使用Java的網格布局可以實現嗎?

我很高興地回答你:「可以!」,我們可以使用GridLayout的另一種構造器方法(簽名不同)來實現:
public GridLayout (int rows,int cols,int hgap,int vgap)
在這個方法中,可以帶上四個整型參數,前兩個我們已經很熟悉了,行數與列數。後面則是兩個新的參數。
第一個是hgap,其中gap的意思是間隙、空隙的意思,而h則是horizontal(水平)的第一個字母。也就是說,我們可以通過hgap參數設置橫向的間隙。
第二個是vgap,v則是vertical(垂直)的第一個字母。也就是說,我們可以通過vgap參數設置縱向的間隙。

自測練習

1)_________________是網格布局管理器。
a.BorderLayout b.GridLayout c.ReseauLayout
d.FlowLayout
利用以下代碼回答問題2、3、4、5:
2)這個布局中有__________行?
a.7行 b.5行 c.6行 d.8行
3)這個布局中有__________列?
a.7行 b.5行 c.6行 d.8行
4)這個布局將容器分為_________個部分?
a.48個 b.35個 c.30個 d.40個
5)第5個部件位於__________位置。
a.左上角 b.左下角 c.右上角 d.右下角 e.中間
6)根據以下界面,編寫一個程序

圖10-12 練習題圖
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
7) 如果我們構建一個5*5的網格布局,但只在該容器中加入17個按鈕,將會出現什麼情況?請編寫一個程序,來試一試效果。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________

練習答案

1)b 沒什麼好解釋的,請大家記住!
2)a 第一個參數是行數,因此是7行。
3)b 第二個參數是列數,因此為5列。
4)b 7行5列,其7*5,35個部分嘛。
5)c 第5個部件是第一行的最後一個,當然在右上角嘛。
6)下面是一個實現的程序實例:
源程序:lianxi10_2.java
import java.awt.*;
import javax.swing.*;
import java.applet.Applet;

public class lianxi10_2 extends JApplet
{
String buttonLabels[]={"1","2","3","4","5","6","7",
"8","9","*","0","#"};

public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(4,3,10,10));

for (int x=0; xpanel1.add(new JButton(buttonLabels[x]));
}
}

7)下面是一個實現的程序實例:
源程序:lianxi10_3.java
import java.awt.*;
import javax.swing.*;
import java.applet.Applet;

public class lianxi10_3 extends JApplet
{

String buttonLabels[]={"No.1","No.2","No.3","No.4","No.5",
"No.6","No.7","No.8","No.9","No.10","No.11","No.12",
"No.13","No.14","No.15","No.16","No.17"};

public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(5,5));

for (int x=0; xpanel1.add(new JButton(buttonLabels[x]));
}
}
這個程序使用javac編譯完後,編寫一個包含這個類的HTML頁面,再用appletviewer來觀察發現運行結果如下圖所示:

圖10-13 練習答案圖

這個輸出是不是令你感到十分意外,整個程序根本不按要求分成5列,所以我們從這里得到一個使用網格布局中要十二分注意的一點:「請別忘了將網格填滿」。否則程序的輸出將不可預料。

一些提示:
如果你真的沒有那麼多東西來「佔領」網格的話,我建議你使用一個空標簽來填補這個空白的網格,使得程序的輸出如你所願。使用空標簽的方法很容易:
panel1.add(new Label(「」));
從這里,我們也看出了,我們學習過的流布局管理器、邊框布局管理器,以及我們剛學習過的網格布局管理器都比較死板,不夠高級。

10.3 組合布局
傳授新知

正如我們在上一小節結束的時候說的一樣,各種布局管理器都有自己的缺點,沒有一種能夠真正地完全滿足我們編寫GUI程序時的要求。
而在Java語言中,允許在容器中加入其他容器,這樣每個容器可以根據自己的需要採用不同的布局管理器,組合成為一個我們所需要的GUI程序界面。這種方法,我們就稱之為組合布局。

注意:
與流布局、邊框布局、網格布局不同,組合布局並不是一個新的布局管理器,它是通過結合各種布局管理器的優點,將它們組合地應用在GUI程序界面的開發中。這是一種布局管理的方法。也可以說是一種GUI程序界面的開發技巧。
當我們設計GUI程序界面時,最好先在紙上把它畫出來,然後「分塊解決」。也就是將能夠組合在一起的部件找出來,將它們放在一個容器里,並為它們選擇合適的布局管理器。然後把這些容器擺放在一起,就解決了。
設計時還要考慮到窗體大小發生改變的時候,引起的部件形體變化。這方面,請你熟記幾個設計技巧:
1) 對於那些要求扁平狀的部件,我們應該將它放置在邊框布局中的南面或北面;
2) 對於那些要求細高狀的部件,我們應該將它放置在邊框布局中的東面或西面;
3) 對於那些可以隨著窗體改變大小部分,我們可以將它放置在邊框布局的中間;
4) 如果我們要求部件保持大小相同,那麼,我們就應該採用網格布局。
下面,我們就通過幾個實際的例子,來讓大家領會和掌握這種設計的思路與方法。

實例說明
我們首先創建一個testCombination.java文件,然後輸入以下源程序:
源程序:testCombination.java
import java.awt.*;
import javax.swing.*;
import java.applet.Applet;

public class testCombination1 extends JApplet
{

public void init()
{
Frame frame1=new Frame("testCombination1");
frame1.setLayout(new BorderLayout());
TextArea text1=new TextArea();
frame1.add(text1,BorderLayout.CENTER);

JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(1,3,10,5));
panel1.add(new JButton("A"));
panel1.add(new JButton("B"));
panel1.add(new JButton("C"));
frame1.add(panel1,BorderLayout.SOUTH);

frame1.pack();
frame1.show();
}
}

然後,我們使用javac編譯這個程序,然後編輯一個顯示這個Java Applet的HTML頁面。最後調用appletviewer來觀察這個頁面,如下圖所示:

圖10-14 程序testCombination.java的輸出

正如上圖所示,程序的輸出與以前不同,各個部件不是顯示在Appletviewer程序框中,而是顯示在另一個窗口中。
這是怎麼回事呢?下面我們就一起來看一下這個程序!

傳授新知

在以前的程序中,我們一直都是使用容器JPanel,面板。而我們在這個程序中引進了一個新的容器Frame。使用了這個容器後,就會新創建一個窗口。這也就是為什麼程序的輸出有這么大的變化的原因。
1)Frame frame1=new Frame("testCombination");
這條語句,定義了一個Frame容器frame1,然後使用new操作符調用構造器方法,後面帶的參數「testCombination」則是這個Frame的標題。

一些提示:
其實大家能Frame所體現出來的效果是很熟悉的,它等價於Windows中的窗體。而Frame的標題就是窗體的標題。

2) frame1.setLayout(new BorderLayout());
與JPanel容器一樣,我們可以調用setLayout方法來設置Frame的布局管理器。在這里,我們將Frame容器frame1的布局管理器設置成為邊框布局管理器(也就是我們在10.1小節中學習過的布局管理器)。
3) frame1.add(text1,BorderLayout.CENTER);
緊接著,我們調用frame1的add方法,將文本區部件text1添加到frame1容器中來。注意我們設置了它的位置:BorderLayout.CENTER。
這是因為,我們希望這個文本區能夠隨著窗體的大小變化而變化。所以適合將其放在在中間位置。
4) panel1.setLayout(new GridLayout(1,3,10,5));
我們又定義了一個JPanel容器panel1,並將其的布局管理器設置為網格布局管理器。並通過指定參數,使得整個panel1被分成1行3列,水平空隙為10的網格。
5) frame1.add(panel1,BorderLayout.SOUTH);
這是組合布局方法最重要的一步,我們將panel1這個容器,加入到了frame1這個容器中去了。並且指定了panel1這個容器在整個frame1中所佔的位置:BorderLayout.SOUTH,也就是下邊。這樣,panel1中包含的三個按鈕就會永遠(不管窗體大小如何改變)呆在文本區的下邊,而且三個按鈕的大小會根據窗體大小的改變而改變。

一些提示:
這是因為,panel1中的按鈕是用網格布局的。
6) frame1.pack();
frame1.show();
與JPanel不一樣,使用Frame容器,不能夠直接顯示了出來。我們必須調用Frame容器的show方法才能使得Frame顯示出來。
而在使用show方法之前,我們還需要使用pack方法將Frame中的內容做一個整合。請記住這里的使用方法。
4 GridBag布局
實例說明

到現在為止,我們已經學習了邊框布局、網格布局以及組合布局,現在大家試一試編寫一個程序,
怎麼樣,挺有難度的吧!完成這個GUI得花很多心思去設計組合,十分討厭,下面我們就使用一個新的布局管理器GridBagLayout來解決這種難題。
首先,輸入以下源程序:
源程序:testGridBag.java
import java.awt.*;
import javax.swing.*;
import java.applet.Applet;

public class testGridBag extends JApplet
{

public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridBagLayout());
GridBagConstraints gbdc=new GridBagConstraints();
gbdc.fill=GridBagConstraints.BOTH;

gbdc.weightx=1;
gbdc.weighty=1;
panel1.add(new JButton("No.1"),gbdc);
panel1.add(new JButton("No.2"),gbdc);
panel1.add(new JButton("No.3"),gbdc);
gbdc.gridwidth=2;
gbdc.gridx=0;
panel1.add(new JButton("No.4"),gbdc);
gbdc.gridx=2;
gbdc.gridwidth=1;
gbdc.gridheight=2;
panel1.add(new JButton("No.5"),gbdc);

gbdc.gridx=0;
gbdc.gridheight=1;
panel1.add(new JButton("No.6"),gbdc);
gbdc.gridx=1;
panel1.add(new JButton("No.7"),gbdc);

gbdc.gridx=0;
gbdc.gridwidth=2;
panel1.add(new JButton("No.8"),gbdc);
gbdc.gridx=2;
gbdc.gridwidth=1;
panel1.add(new JButton("No.9"),gbdc);
}
}

在這個程序中,我們使用了GridBagLayout輕松地完成了這個界面的設計,允分凸現出它的強大。可以這么說,GridBagLayout是Java語言中最強大的布局管理器。
GridBagLayout,從名字上看,就知道它與GridLayout有一定的淵源,是的,GridBagLayout的確與其十分類似,也是使用網格來進行布局管理的。但與GridLayout(網格布局)不同的是,GridBagLayout不像網格布局一相,需要所有的部件的大小、形狀相同。而且還可以將某一個部件放在一個固定的位置上。
下面,我們一起來分析一下testGridBag.java程序。
1) panel1.setLayout(new GridBagLayout());
在調用setLayout方法時,指定為GridBagLaoyout,使panel1使用GridBag布局管理。
2) GridBagConstraints gbdc=new GridBagConstraints();
GridBagLayout布局管理器是通過一個GridBagConstraints類來實現神奇的效果的。所以,我們要在使用時先定義一個GridBagConstraints類的對象。在這個程序中,我們定義了一個GridBagConstraints類的對象gbdc。
3) gbdc.fill=GridBagConstraints.BOTH;
由於網格單元可能比該單元中的部件大,如果是這樣,部件放置在單元格內會有一些多餘空間。在默認情況下,部件不會擴張,也就是不會填充這個多餘空間。
GridBagConstraints提供了一個fill屬性,我們可以通過設置它的值來起到不同的效果。
¨ GridBagConstraints.NONE:不擴張,是默認值;
¨ GridBagConstraints.HORIZONTAL:部件水平擴張,將水平方向的多餘空間填滿;
¨ GridBagConstraints.VERTICAL:部件垂直擴張,將垂直方向的多餘空間填滿;
¨ GridBagConstraints.BOTH:部件同時向兩個方向擴張,將單元格填滿。
4) gbdc.weightx=1;
gbdc.weighty=1;
weightx和weighty是GridBagConstraints提供的另一對屬性。它的取值是整型數,默認值為0。用來設置行(weightx)、列(weighty)的「重量」,如果值為0的話,所有的部件都會緊收在一起,聚集在中央,如圖10-17所示。
而如果取值為其它數字,則會根據值來分配空間。
5) panel1.add(new JButton("No.1"),gbdc);
panel1.add(new JButton("No.2"),gbdc);
panel1.add(new JButton("No.3"),gbdc);
在沒有任何約束的時候,向gbdc中添加按鈕,這時效果與採用網格布局的效果完全一樣。一個接著一個地「佔領」單元格。

6) gbdc.gridwidth=2;
gbdc.gridx=0;
panel1.add(new JButton("No.4"),gbdc);

由於第四個按鈕(No.4)是寬度是2,在GridBagLayout中,是由gridwidth屬性來控制添加進入的部件的寬度的。
我們通過gbdc.gridwidth=2將其設置為2,這樣,再添加進入的部件就會變成為2個單元格的寬度。
另外,我們再使用gbdc.gridx=0讓其另起一行,從最左邊的單元格開始填充。
因此,我們發現第四個按鈕被加在了第二行,寬度為2個單元格。

7) gbdc.gridx=2;
gbdc.gridwidth=1;
gbdc.gridheight=2;
panel1.add(new JButton("No.5"),gbdc);
接下來,我們要擺放第五個按鈕,這個按鈕將從第3個單元開始填充,其寬度為一個單元格,而高度則為兩個單元格。
因此,我們首先使用用gbdc.gridx=2,使得下一個添加的部件(第五個按鈕)放入第3個單元格(0代表第1個單元格,因此第3個單元格應該是2)。
由於,前面我們已經將gridwidth設置為2了,因此,我們需要使用gbdc.gridwidth=1,將其值設置回1。
最後使用gdbc.gridheight=2,使得添入的部件的單元格縱向跨越兩個單元格。

8) gbdc.gridx=0;
gbdc.gridheight=1;
panel1.add(new JButton("No.6"),gbdc);
我想這一段程序,大家應該都不會再有什麼理解上的問題了吧!主要提醒大家注意的是,我們使用gbdc.gridheight=1將單元格縱向跨度改成了默認值1。這是因為我們在前面需要時將其改成了2,所以在此需要將其改回來。

實例說明
為了更好地理解這個強大的GridBagLayout布局管理器,我們再來做一個有趣的實驗。首先,我們創建一個testGridBag2.java
源程序:testGridBag2.java
import java.awt.*;
import javax.swing.*;
import java.applet.Applet;

public class testGridBag2 extends JApplet
{

public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridBagLayout());
GridBagConstraints gbdc=new GridBagConstraints();

panel1.add(new JButton("No.1"),gbdc);
panel1.add(new JButton("No.2"),gbdc);
setSize(300,200);
}
}

然後我們使用滑鼠改變一下窗口的大小,看一下,這兩個按鈕有什麼變化?你會驚奇地發現,窗口改變了大小,兩個按鈕的大小卻沒有變,而且一直呆在正中央的位置。

一些說明:
在這個程序中,我們使用了一個以前沒有用過的語句:setsize(300.200),它的功能是在程序中設置窗口的大小。

現在我們對這個程序做一些修改!將添加兩個按鈕的兩條語句:
panel1.add(new JButton("No.1"),gbdc);
panel1.add(new JButton("No.2"),gbdc);
將它們擴展為:
gbdc.weightx=1;
panel1.add(new JButton("No.1"),gbdc);
gbdc.weightx=3;
panel1.add(new JButton("No.2"),gbdc);

為什麼會得到這個效果呢?我們在程序中添加按鈕的程序段前加入一句:
gbdc.fill=GridBagConstraints.HORIZONTAL;
再重新編譯一下程序,再看看程序的輸出有什麼變化!
在得到結果之前,自己可以想像一下結果,然後看一下程序的實際輸出與你的想法是否相吻合。
我們驚奇地發現,第二個按鈕,突然變得十分寬起來(如圖10-20所示)。這是因為放置第二個按鈕的單元格的寬度是3,而第一個按鈕的寬度是1。而且,我們又讓第二個按鈕橫向擴展,因此得到了這樣的輸出結果。

相信實驗做到這里,不須我說,大家也會有一些心得體會了。但是GridBagLayout遠不止這一點,大家應該多做試驗,才能夠在真實的使用環境中有效地掌握GridBagLayout。

㈩ qt自動設置key編號

在一個應用程序上工作,我有選項卡名稱的問題。 當我點擊按鈕(新)時,我想動態創建冊段新標簽。
使用此功能,我創建新文件:
bool MainWindow::toolbarNewFile()
{

QWidget *page = new QWidget;

QTextEdit *codeEditor = new QTextEdit;

QGridLayout *layout = new QGridLayout;

layout->addWidget(codeEditor);

page->setLayout(layout);

tab_widget->addTab(page,"File");

return true;
}

但所有標簽都有名稱「FILE」
如何在標簽名稱編號中設置。 當我製作新選項卡時,自動設置選項卡的編號如下。
文件-1,文件-2,文件-3
我試著設置counter i=0; 並在addTab(page,"File-"宏碧+ i++); 不起作用。

I working on one application and I have problem with tab name. When I click on push button (NEW) I want to dynamically create new tab.
With this function i create new file:
bool MainWindow::toolbarNewFile()
{

QWidget *page = new QWidget;

QTextEdit *codeEditor = new QTextEdit;

QGridLayout *layout = new QGridLayout;

layout->addWidget(codeEditor);

page->setLayout(layout);

tab_widget->addTab(page,"File");

return true;
}

But all tabs have name "FILE"
How to set in tab name number. When i make new tab auto set number of the tab like this.
File-1, File-2, File-3
I try to set counter i=0; and in addTab(page,"File-"+ i++); Doesn't work.

原文:https://stackoverflow.com/questions/14692433
2022-01-02 10:01
滿意答案
您需要將整數轉換為QString才能將其連接到QString 。 更好的是,您可以使用QString :: arg函數,並且可以非常輕松地獲取可蔽姿舉讀且可能更快的代碼:
tab_widget->addTab(page, QString("File-%1").arg(i++));

i的班級中的欄位初始化為1。

You need to covert integer to the QString to be able to concat it to the QString. Even better, you can use QString::arg function and get readable and potentially faster code very easily:
tab_widget->addTab(page, QString("File-%1").arg(i++));

Where i is field in your class initialized to 1.
相關問答更多
PyQt4(QTabWidget)如何更改Tab頁面的位置(PyQt4 (QTabWidget) how to change position of a Tab Page)
好的,我發現了自己的問題。 我把self.ui.tabWidget.tabCloseRequested.connect(self.onTabClose)放在與創建新標簽的方法相同的方法中。 這意味著如果創建了5個選項卡,那麼當一個選項卡關閉時,tabCloseReqested會觸發5次。 通過將此連接語句放在我的類的init中,就像我應該做的那樣,它只定義一次,並且僅在關閉選項卡時觸發一次。 OK, I found the problem my self. I had put the self.u...
如何在QTabWidget標頭中設置QWidget?(How to set QWidget in QTabWidget header?)
您必須使用setTabButton函數: void QTabBar :: setTabButton(int index,ButtonPosition position,QWidget * widget) 在選項卡索引上設置小部件。 小部件根據位置放置在左側或右側。 隱藏任何先前設置的小部件。 標簽欄將取得窗口小部件的所有權,因此在銷毀時,標簽欄將刪除此處設置的所有窗口小部件,除非您在設置其他窗口小部件(或0)後單獨重新顯示窗口小部件。 該功能在Qt 4.5中引入。 這與QTabWidget而與QT...
是否可以通過製表符號引用QTabWidget的單個選項卡?(Is it possible to reference indivial tabs of a QTabWidget by tab number?)
如果您希望該選項卡具有特定索引,請使用widget(): QWidget* tab = tabWidget->widget( index ); If you want the tab with a certain index, use widget(): QWidget* tab = tabWidget->widget( index );
如何在QTabWidget中為布局設置布局?(How can I set a layout to a tab in QTabWidget?)
它將始終位於左上角。 您可以在自己的基礎上添加另一個小部件,然後將小部件放在該小部件的中間,或者將小部件設置為選項卡的大小並將其內容放在中間。 您可以使用QWidget的setLayout方法來設置窗口小部件布局。 Following @Satus idea, I create a new QFrame, set the minimum size as the size of myTabWidget, set a horizontal layout and add myCustomWidget i...
QT:逃離QTabWidget(QT: Escape from QTabWidget)
來自doc: void QWidget::setTabOrder ( QWidget * first, QWidget * second ) [static] 將第二個窗口小部件放在焦點順序中的第一個窗口小部件之後。 請注意,由於第二個小部件的Tab鍵順序已更改,您應該按如下順序排序: setTabOrder(a, b); // a to b setTabOrder(b, c); // a to b to c setTabOrder(c, d); // a to b to c to d ...
QTabWidget拒絕自動調整大小(QTabWidget refusing to auto-resize)
這是如何使Qt Widget隨窗口大小增長而重復嗎? ? 我認為它是重復的,因為如果你的小部件樹中的每個項目都有一個布局,我在Qt 4.7上的測試給出了以下輸出,右邊是我的對象檢查器。 我只是放入小部件並打好它們,我沒有改變任何尺寸的東西來擴展,因為這絕對沒必要! 左邊是正在運行的exe,右邊是Creator截圖。 這是我的用戶界面: <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</...
Qt QTabWidget - 自動設置標簽名稱編號(Qt QTabWidget - auto set tab name number)
您需要將整數轉換為QString才能將其連接到QString 。 更好的是,您可以使用QString :: arg函數,並且可以非常輕松地獲取可讀且可能更快的代碼: tab_widget->addTab(page, QString("File-%1").arg(i++)); i的班級中的欄位初始化為1。 You need to covert integer to the QString to be able to concat it to the QString. Even better, yo...
如何在Qt上從QTabWidget獲取currentTabName?(How to get currentTabName from QTabWidget on Qt?)
正如Chris Kawa 在這里回答的那樣,這是當前小部件的對象名稱。 從代碼我可以這樣得到它: QString currentTabName = tabWidget->currentWidget()->objectName(); 注意 :正如文檔建議的那樣,確保在使用tabWidget->currentWidget()時檢查nullptr 。 As Chris Kawa answered here this is the object name of the current widget. F...
如何在QTabWidget中只設置一個不能在Qt中移動的選項卡?(How to set only one tab in a QTabWidget as not moveable in Qt?)
看看QTabBar的源代碼( QTabBar子元素),似乎這是不可能的。 所有選項卡只有一個movable屬性。 但是,您可以嘗試以下方法: 子類QTabBar並在拖動開始之前捕獲滑鼠按下事件以啟用或禁用選項卡的移動。 像這樣的東西: void MyTabBar::mousePressEvent(QMouseEvent *event) { // all tabs movable except first setMovable(tabAt(event->pos()) != 0); ...
樣式化QTabWidget(Styling QTabWidget)
似乎焦點矩形由正在使用的QStyle (不要與樣式表混淆)處理。 您可以編寫一個QStyle子類並將其應用於您的QTabWidget 。 子類應覆蓋drawControl()方法,如果當前正在繪制焦點矩形,則不執行任何操作。 子類看起來像這樣: NoFocusRectStyle.h #ifndef NOFOCUSRECTSTYLE_H #define NOFOCUSRECTSTYLE_H #include <QWindowsVistaStyle> // or the QStyle subclas...

閱讀全文

與setlayout有哪些方法相關的資料

熱點內容
拉大蒜器蓋的安裝方法 瀏覽:549
光滑牆磚安裝方法 瀏覽:735
latoja使用方法視頻 瀏覽:983
天津治療腦血栓最新方法 瀏覽:16
辣椒紅色素使用方法 瀏覽:818
印刷機少錫的原因及解決方法 瀏覽:806
如何挑選海參有幾種方法 瀏覽:325
鼻咽通氣管的使用方法 瀏覽:239
腿部記憶訓練方法 瀏覽:971
101x41用什麼方法算簡更 瀏覽:436
大蒜治腰間盤突出最佳方法 瀏覽:202
太倉食品安全檢測方法 瀏覽:203
大白輔助燈安裝方法 瀏覽:794
東莞石龍如何最快方法到佛山高明 瀏覽:682
桃紅的修剪方法圖片 瀏覽:959
護理研究中常用抽樣方法 瀏覽:12
用什麼捕蝦最好的方法 瀏覽:314
髖關節的鍛煉方法 瀏覽:485
心理焦慮症怎麼治療最好的方法 瀏覽:840
16年五糧液真假鑒別方法 瀏覽:284