java-GUI編程之佈局類型介紹

来源:https://www.cnblogs.com/kohler21/archive/2022/04/03/16094173.html
-Advertisement-
Play Games

java使用AWT和Swing相關的類可以完成圖形化界面編程,其中AWT的全稱是抽象視窗工具集(Abstract Window Toolkit),它是sun公司最早提供的GUI庫,這個GUI庫提供了一些基本功能,但這個GUI庫的功能比較有限,所以後來sun公司又提供了Swing庫。通過使用AWT和S ...


java使用AWT和Swing相關的類可以完成圖形化界面編程,其中AWT的全稱是抽象視窗工具集(Abstract Window Toolkit),它是sun公司最早提供的GUI庫,這個GUI庫提供了一些基本功能,但這個GUI庫的功能比較有限,所以後來sun公司又提供了Swing庫。通過使用AWT和Swing提供的圖形化界面組件庫,java的圖形化界面編程非常簡單,程式只需要依次創建所需的圖形組件,並以合適的方式將這些組件組織在一起,就可以開發出非常美觀的用戶界面。

AWT簡介

當 JDK 1.0發佈時, Sun 提供了 一套基本的GUI類庫,這個GUI類庫希望可以在所有平臺下都能運行 , 這套基本類庫被稱為"抽象視窗工具集 CAbstract Window Toolkit )",它為Java應用程式提供了基本的圖形組件 。 AWT是視窗框架,它從不同平臺的視窗系統中抽取出共同組件 , 當程式運行時,將這些組件的創建和動作委托給程式所在的運行平臺 。 簡而言之 ,當使用 AWT 編寫圖形界面應用 時, 程式僅指定了界面組件的位置和行為,並未提供真正的實現,JVM調用操作系統本地的圖形界面來創建和平臺 一致的對等體 。

​ 使用AWT創建的圖形界面應用和所在的運行平臺有相同的界面風格 , 比如在 Windows 操作系統上,它就表現出 Windows 風格 ; 在 UNIX 操作系統上,它就表現出UNIX 風格 。 Sun 希望採用這種方式來實現 " Write Once, Run Anywhere " 的目標 。

AWT繼承體系

  • Component:代表一個能以圖形化方式顯示出來,並可與用戶交互的對象,例如 Button 代表一個按鈕,TextField 代表 一個文本框等;
  • MenuComponent:則代表圖形界面的菜單組件,包括 MenuBar (菜單條)、 Menultem (菜單項)等子類。

其中 Container 是一種特殊的 Component,它代表一種容器,可以盛裝普通的 Component。

AWT中還有一個非常重要的介面叫LayoutManager ,如果一個容器中有多個組件,那麼容器就需要使用LayoutManager來管理這些組件的佈局方式。

Container容器

Container繼承體系

  • ​ Winow是可以獨立存在的頂級視窗,預設使用BorderLayout管理其內部組件佈局;
  • ​ Panel可以容納其他組件,但不能獨立存在,它必須內嵌其他容器中使用,預設使用FlowLayout管理其內部組件佈局;
  • ​ ScrollPane 是 一個帶滾動條的容器,它也不能獨立存在,預設使用 BorderLayout 管理其內部組件佈局;

常見API

Component作為基類,提供瞭如下常用的方法來設置組件的大小、位置、可見性等。

方法簽名 方法功能
setLocation(int x, int y) 設置組件的位置。
setSize(int width, int height) 設置組件的大小。
setBounds(int x, int y, int width, int height) 同時設置組件的位置、大小。
setVisible(Boolean b): 設置該組件的可見性。

Container作為容器根類,提供瞭如下方法來訪問容器中的組件

方法簽名 方法功能
Component add(Component comp) 向容器中添加其他組件 (該組件既可以是普通組件,也可以 是容器) , 並返回被添加的組件 。
Component getComponentAt(int x, int y): 返回指定點的組件 。
int getComponentCount(): 返回該容器內組件的數量 。
Component[] getComponents(): 返回該容器內的所有組件 。

容器演示

Window


import java.awt.*;

public class FrameDemo {

    public static void main(String[] args) {
        //1.創建視窗對象
        Frame frame = new Frame("這是第一個視窗容器");

        //設置視窗的位置和大小

        frame.setBounds(100,100,500,300);

        //設置視窗可見
        frame.setVisible(true);
    }
}

Panel

​ ​


import java.awt.*;
public class PanelDemo {
    public static void main(String[] args) {
        //1.創建Frame容器對象
        Frame frame = new Frame("這裡在測試Panel");
        //2.創建Panel容器對象
        Panel panel = new Panel();

        //3.往Panel容器中添加組件
        panel.add(new TextField("這是一個測試文本"));
        panel.add(new Button("這是一個測試按鈕"));

        //4.把Panel添加到Frame中
        frame.add(panel);

        //5.設置Frame的位置和大小
        frame.setBounds(30,30,500,300);

        //6.設置Frame可見
        frame.setVisible(true);
    }
}

ScrollPane

​ ​


import java.awt.*;

public class ScrollPaneDemo {

    public static void main(String[] args) {
        //1.創建Frame視窗對象
        Frame frame = new Frame("這裡測試ScrollPane");

        //2.創建ScrollPane對象,並且指定預設有滾動條
        ScrollPane scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);

        //3.往ScrollPane中添加組件
        scrollPane.add(new TextField("這是測試文本"));
        scrollPane.add(new Button("這是測試按鈕"));

        //4.把ScrollPane添加到Frame中
        frame.add(scrollPane);

        //5.設置Frame的位置及大小
        frame.setBounds(30,30,500,300);

        //6.設置Frame可見
        frame.setVisible(true);

    }
}

程式明明向 ScrollPane 容器中添加了 一個文本框和一個按鈕,但只能看到 一個按鈕,卻看不到文本框 ,這是為什麼 呢?這是因為ScrollPane 使用 BorderLayout 佈局管理器的緣故,而 BorderLayout 導致了該容器中只有一個組件被顯示出來 。

LayoutManager佈局管理器

之前,我們介紹了Component中有一個方法 setBounds() 可以設置當前容器的位置和大小,但是我們需要明確一件事,如果我們手動的為組件設置位置和大小的話,就會造成程式的不通用性,例如:

Label label = new Label("你好,世界");

創建了一個lable組件,很多情況下,我們需要讓lable組件的寬高和“你好,世界”這個字元串自身的寬高一致,這種大小稱為最佳大小。由於操作系統存在差異,例如在windows上,我們要達到這樣的效果,需要把該Lable組件的寬和高分別設置為100px,20px,但是在Linux操作系統上,可能需要把Lable組件的寬和高分別設置為120px,24px,才能達到同樣的效果。

如果要讓我麽的程式在不同的操作系統下,都有相同的使用體驗,那麼手動設置組件的位置和大小,無疑是一種災難,因為有太多的組件,需要分別設置不同操作系統下的大小和位置。為瞭解決這個問題,Java提供了LayoutManager佈局管理器,可以根據運行平臺來自動調整組件大小,程式員不用再手動設置組件的大小和位置了,只需要為容器選擇合適的佈局管理器即可。


FlowLayout

​ 在 FlowLayout 佈局管理器 中,組件像水流一樣向某方向流動 (排列) ,遇到障礙(邊界)就折回,重頭開始排列 。在預設情況下, FlowLayout 佈局管理器從左向右排列所有組件,遇到邊界就會折回下一行重新開始。

構造方法 方法功能
FlowLayout() 使用預設 的對齊方式及預設的垂直間距、水平間距創建 FlowLayout 佈局管理器。
FlowLayout(int align) 使用指定的對齊方式及預設的垂直間距、水平間距創建 FlowLayout 佈局管理器。
FlowLayout(int align,int hgap,int vgap) 使用指定的對齊方式及指定的垂直問距、水平間距創建FlowLayout 佈局管理器。

FlowLayout 中組件的排列方向(從左向右、從右向左、從中間向兩邊等) , 該參數應該使用FlowLayout類的靜態常量 : FlowLayout. LEFT 、 FlowLayout. CENTER 、 FlowLayout. RIGHT ,預設是左對齊。

FlowLayout 中組件中間距通過整數設置,單位是像素,預設是5個像素。

代碼演示:

​​


import java.awt.*;

public class FlowLayoutDemo {

    public static void main(String[] args) {
        //1.創建Frame對象
        Frame frame = new Frame("這裡測試FlowLayout");
        //2.修改Frame容器的佈局管理器為FlowLayout
        frame.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));

        //3.往Frame中添加100個button
        for (int i = 0; i < 100; i++) {
            frame.add(new Button("按鈕"+i));
        }

        //4.設置Frame為最佳大小
        frame.pack();
        //5.設置Frame可見
        frame.setVisible(true);
    }
}

BorderLayout

BorderLayout 將容器分為 EAST 、 SOUTH 、 WEST 、 NORTH 、 CENTER五個區域,普通組件可以被放置在這 5 個區域的任意一個中 。 BorderLayout佈局 管理器的佈局示意圖如圖所示 。

​​


當改變使用 BorderLayout 的容器大小時, NORTH 、 SOUTH 和 CENTER區域水平調整,而 EAST 、 WEST 和 CENTER 區域垂直調整。使用BorderLayout 有如下兩個註意點:

  1. 當向使用 BorderLayout 佈局管理器的容器中添加組件時 , 需要指定要添加到哪個區域中 。 如果沒有指定添加到哪個區域中,則預設添加到中間區域中;
  2. 如果向同一個區域中添加多個組件時 , 後放入的組件會覆蓋先放入的組件;
構造方法 方法功能
BorderLayout() 使用預設的水平間距、垂直 間距創建 BorderLayout 佈局管理器 。
BorderLayout(int hgap,int vgap): 使用指定的水平間距、垂直間距創建 BorderLayout 佈局管理器。

代碼演示1:

​​​


import java.awt.*;

public class BorderLayoutDemo1 {

    public static void main(String[] args) {
        //1.創建Frame對象
        Frame frame = new Frame("這裡測試BorderLayout");
        //2.指定Frame對象的佈局管理器為BorderLayout
        frame.setLayout(new BorderLayout(30,5));
        //3.往Frame指定東南西北中各添加一個按鈕組件
        frame.add(new Button("東側按鈕"), BorderLayout.EAST);
        frame.add(new Button("西側按鈕"), BorderLayout.WEST);
        frame.add(new Button("南側按鈕"), BorderLayout.SOUTH);
        frame.add(new Button("北側按鈕"), BorderLayout.NORTH);
        frame.add(new Button("中間按鈕"), BorderLayout.CENTER);
        //4.設置Frame為最佳大小
        frame.pack();
        //5.設置Frame可見
        frame.setVisible(true);
    }
}

如果不往某個區域中放入組件,那麼該區域不會空白出來,而是會被其他區域占用

代碼演示2:

​​​​


import java.awt.*;

public class BorderLayoutDemo2 {

    public static void main(String[] args) {
        //1.創建Frame對象
        Frame frame = new Frame("這裡測試BorderLayout");
        //2.指定Frame對象的佈局管理器為BorderLayout
        frame.setLayout(new BorderLayout(30,5));
        //3.往Frame指定南,北,放入一個按鈕,往中間區域放入一個Panel

        frame.add(new Button("南側按鈕"), BorderLayout.SOUTH);
        frame.add(new Button("北側按鈕"), BorderLayout.NORTH);

        Panel panel = new Panel();
        panel.add(new TextField("測試文本"));
        panel.add(new Button("中間按鈕"));

        frame.add(panel, BorderLayout.CENTER);
	
        //4.設置Frame為最佳大小
        frame.pack();
        //5.設置Frame可見
        frame.setVisible(true);
    }
}

2.4.3 GridLayout

​ GridLayout 佈局管理器將容器分割成縱橫線分隔的網格 , 每個網格所占的區域大小相同。當向使用 GridLayout 佈局管理器的容器中添加組件時, 預設從左向右、 從上向下依次添加到每個網格中 。 與 FlowLayout不同的是,放置在 GridLayout 佈局管理器中的各組件的大小由組件所處的區域決定(每 個組件將自動占滿整個區域) 。

構造方法 方法功能
GridLayout(int rows,in t cols) 採用指定的行數、列數,以及預設的橫向間距、縱向間距將容器 分割成多個網格
GridLayout(int rows,int cols,int hgap,int vgap) 採用指定 的行數、列 數 ,以及指定的橫向間距 、 縱向間距將容器分割成多個網格。

案例:

​ 使用Frame+Panel,配合FlowLayout和GridLayout完成一個計算器效果。

​​​​​


代碼:

import java.awt.*;

public class GridLayoutDemo{

    public static void main(String[] args) {

        //1.創建Frame對象,並且標題設置為計算器
        Frame frame = new Frame("計算器");

        //2.創建一個Panel對象,並且往Panel中放置一個TextField組件
        Panel p1 = new Panel();
        p1.add(new TextField(30));

        //3.把上述的Panel放入到Frame的北側區域
        frame.add(p1,BorderLayout.NORTH);

        //4.創建一個Panel對象,並且設置其佈局管理器為GridLayout
        Panel p2 = new Panel();
        p2.setLayout(new GridLayout(3,5,4,4));

        //5.往上述Panel中,放置15個按鈕,內容依次是:0,1,2,3,4,5,6,7,8,9,+,-,*,/,.
        for (int i = 0; i < 10; i++) {
            p2.add(new Button(i+""));
        }
        p2.add(new Button("+"));
        p2.add(new Button("-"));
        p2.add(new Button("*"));
        p2.add(new Button("/"));
        p2.add(new Button("."));

        //6.把上述Panel添加到Frame的中間區域中國
        frame.add(p2);
        //7.設置Frame為最佳大小
        frame.pack();

        //8.設置Frame可見
        frame.setVisible(true);

    }
}

GridBagLayout

GridBagLayout 佈局管理器的功能最強大 , 但也最複雜,與 GridLayout 佈局管理器不同的是, 在GridBagLayout 佈局管理器中,一個組件可以跨越一個或多個網格 , 並可以設置各網格的大小互不相同,從而增加了佈局的靈活性 。 當視窗的大小發生變化時 , GridBagLayout 佈局管理器也可以準確地控制視窗各部分的拉伸 。

​​​​​


由於在GridBagLayout 佈局中,每個組件可以占用多個網格,此時,我們往容器中添加組件的時候,就需要具體的控制每個組件占用多少個網格,java提供的GridBagConstaints類,與特定的組件綁定,可以完成具體大小和跨越性的設置。

GridBagConstraints API:

成員變數 含義
gridx 設置受該對象控制的GUI組件左上角所在網格的橫向索引
gridy 設置受該對象控制的GUI組件左上角所在網格的縱向索引
gridwidth 設置受該對象控制的 GUI 組件橫向跨越多少個網格,如果屬性值為 GridBagContraints.REMAIND,則表明當前組件是橫向最後一個組件,如果屬性值為GridBagConstraints.RELATIVE,表明當前組件是橫向倒數第二個組件。
gridheight 設置受該對象控制的 GUI 組件縱向跨越多少個網格,如果屬性值為 GridBagContraints.REMAIND,則表明當前組件是縱向最後一個組件,如果屬性值為GridBagConstraints.RELATIVE,表明當前組件是縱向倒數第二個組件。
fill 當"顯示區域"大於"組件"的時候,如何調整組件 :
GridBagConstraints.NONE : GUI 組件不擴大
GridBagConstraints.HORIZONTAL: GUI 組件水平擴大 以 占據空白區域
GridBagConstraints.VERTICAL: GUI 組件垂直擴大以占據空白區域
GridBagConstraints.BOTH: GUI 組件水平 、 垂直同時擴大以占據空白區域.
ipadx 設置受該對象控制的 GUI 組件橫向內部填充的大小,即 在該組件最小尺寸的基礎上還需要增大多少.
ipady 設置受該對象控制的 GUI 組件縱向內部填充的大小,即 在該組件最小尺寸的基礎上還需要增大多少.
insets 設置受該對象控制 的 GUI 組件的 外部填充的大小 , 即該組件邊界和顯示區 域邊界之間的 距離 .
weightx 設置受該對象控制 的 GUI 組件占據多餘空間的水平比例, 假設某個容器 的水平線上包括三個 GUI 組件, 它們的水平增加比例分別是 1 、 2 、 3 , 但容器寬度增加 60 像素 時,則第一個組件寬度增加 10 像素 , 第二個組件寬度增加 20 像素,第三個組件寬度增加 30 像 素。 如 果其增 加比例為 0 , 則 表示不會增加 。
weighty 設置受該對象控制 的 GUI 組件占據多餘空間的垂直比例
anchor 設置受該對象控制 的 GUI 組件在其顯示區域中的定位方式:
GridBagConstraints .CENTER (中 間 )
GridBagConstraints.NORTH (上中 )
GridBagConstraints.NORTHWEST (左上角)
GridBagConstraints.NORTHEAST (右上角)
GridBagConstraints.SOUTH (下中)
GridBagConstraints.SOUTHEAST (右下角)
GridBagConstraints.SOUTHWEST (左下角)
GridBagConstraints.EAST (右中)
GridBagConstraints.WEST (左中)

GridBagLayout使用步驟:

1.創建GridBagLaout佈局管理器對象,並給容器設置該佈局管理器對象;

2.創建GridBagConstraints對象,並設置該對象的控制屬性:

	gridx: 用於指定組件在網格中所處的橫向索引;

	gridy: 用於執行組件在網格中所處的縱向索引;

	gridwidth: 用於指定組件橫向跨越多少個網格;

	gridheight: 用於指定組件縱向跨越多少個網格;

3.調用GridBagLayout對象的setConstraints(Component c,GridBagConstraints gbc )方法,把即將要添加到容器中的組件c和GridBagConstraints對象關聯起來;

4. 把組件添加到容器中;

案例:

​ 使用Frame容器,設置GridBagLayout佈局管理器,實現下圖中的效果:

​​​​​


演示代碼:

import java.awt.*;

public class GridBagLayoutDemo {

    public static void main(String[] args) {
        //1.創建Frame對象
        Frame frame = new Frame("這裡是GridBagLayout測試");

        //2.創建GridBagLayout對象
        GridBagLayout gbl = new GridBagLayout();

        //3.把Frame對象的佈局管理器設置為GridBagLayout
        frame.setLayout(gbl);

        //4.創建GridBagConstraints對象
        GridBagConstraints gbc = new GridBagConstraints();

        //5.創建容量為10的Button數組
        Button[] bs = new Button[10];

        //6.遍曆數組,初始化每一個Button
        for (int i = 0; i < bs.length; i++) {
            bs[i] = new Button("按鈕"+(i+1));
        }

        //7.設置所有的GridBagConstraints對象的fill屬性為GridBagConstraints.BOTH,當有空白區域時,組件自動擴大占滿空白區域
        gbc.fill=GridBagConstraints.BOTH;

        //8.設置GridBagConstraints對象的weightx設置為1,表示橫向擴展比例為1
        gbc.weightx=1;

        //9.往frame中添加數組中的前3個Button
        addComponent(frame,bs[0],gbl,gbc);
        addComponent(frame,bs[1],gbl,gbc);
        addComponent(frame,bs[2],gbl,gbc);

        //10.把GridBagConstraints的gridwidth設置為GridBagConstraints.REMAINDER,則表明當前組件是橫向最後一個組件
        gbc.gridwidth=GridBagConstraints.REMAINDER;

        //11.把button數組中第四個按鈕添加到frame中
        addComponent(frame,bs[3],gbl,gbc);


        //12.把GridBagConstraints的weighty設置為1,表示縱向擴展比例為1
        gbc.weighty=1;

        //13.把button數組中第5個按鈕添加到frame中
        addComponent(frame,bs[4],gbl,gbc);

        //14.把GridBagConstaints的gridheight和gridwidth設置為2,表示縱向和橫向會占用兩個網格
        gbc.gridheight=2;
        gbc.gridwidth=2;

        //15.把button數組中第6個按鈕添加到frame中
        addComponent(frame,bs[5],gbl,gbc);

        //16.把GridBagConstaints的gridheight和gridwidth設置為1,表示縱向會占用1個網格
        gbc.gridwidth=1;
        gbc.gridheight=1;
        //17.把button數組中第7個按鈕添加到frame中
        addComponent(frame,bs[6],gbl,gbc);

        //18.把GridBagConstraints的gridwidth設置為GridBagConstraints.REMAINDER,則表明當前組件是橫向最後一個組件
        gbc.gridwidth=GridBagConstraints.REMAINDER;

        //19.把button數組中第8個按鈕添加到frame中
        addComponent(frame,bs[7],gbl,gbc);

        //20.把GridBagConstaints的gridwidth設置為1,表示縱向會占用1個網格
        gbc.gridwidth=1;

        //21.把button數組中第9、10個按鈕添加到frame中
        addComponent(frame,bs[8],gbl,gbc);
        addComponent(frame,bs[9],gbl,gbc);

        //22.設置frame為最佳大小
        frame.pack();

        //23.設置frame可見
        frame.setVisible(true);
    }

    public static void addComponent(Container container,Component c,GridBagLayout gridBagLayout,GridBagConstraints gridBagConstraints){
        gridBagLayout.setConstraints(c,gridBagConstraints);
        container.add(c);
    }
}

CardLayout

CardLayout 佈局管理器以時間而非空間來管理它裡面的組件,它將加入容器的所有組件看成一疊卡片(每個卡片其實就是一個組件),每次只有最上面的那個 Component 才可見。就好像一副撲克牌,它們疊在一起,每次只有最上面的一張撲克牌才可見.

方法名稱 方法功能
CardLayout() 創建預設的 CardLayout 佈局管理器。
CardLayout(int hgap,int vgap) 通過指定卡片與容器左右邊界的間距 C hgap) 、上下邊界 Cvgap) 的間距來創建 CardLayout 佈局管理器.
first(Container target) 顯示target 容器中的第一張卡片.
last(Container target) 顯示target 容器中的最後一張卡片.
previous(Container target) 顯示target 容器中的前一張卡片.
next(Container target) 顯示target 容器中的後一張卡片.
show(Container taget,String name) 顯 示 target 容器中指定名字的卡片.

案例:

​ 使用Frame和Panel以及CardLayout完成下圖中的效果,點擊底部的按鈕,切換卡片

演示代碼:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class CardLayoutDemo {

    public static void main(String[] args) {
        //1.創建Frame對象
        Frame frame = new Frame("這裡測試CardLayout");

        //2.創建一個String數組,存儲不同卡片的名字
        String[] names = {"第一張","第二張","第三張","第四張","第五張"};

        //3.創建一個Panel容器p1,並設置其佈局管理器為CardLayout,用來存放多張卡片
        CardLayout cardLayout = new CardLayout();
        Panel p1 = new Panel();
        p1.setLayout(cardLayout);

        //4.往p1中存儲5個Button按鈕,名字從String數組中取
        for (int i = 0; i < 5; i++) {
            p1.add(names[i],new Button(names[i]));
        }

        //5.創建一個Panel容器p2,用來存儲5個按鈕,完成卡片的切換
        Panel p2 = new Panel();

        //6.創建5個按鈕,並給按鈕設置監聽器
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String command = e.getActionCommand();
                switch (command){
                    case "上一張":
                        cardLayout.previous(p1);
                        break;
                    case "下一張":
                        cardLayout.next(p1);
                        break;
                    case "第一張":
                        cardLayout.first(p1);
                        break;
                    case "最後一張":
                        cardLayout.last(p1);
                        break;
                    case "第三張":
                        cardLayout.show(p1,"第三張");
                        break;
                }
            }
        };

        Button b1 = new Button("上一張");
        Button b2 = new Button("下一張");
        Button b3 = new Button("第一張");
        Button b4 = new Button("最後一張");
        Button b5 = new Button("第三張");
        b1.addActionListener(listener);
        b2.addActionListener(listener);
        b3.addActionListener(listener);
        b4.addActionListener(listener);
        b5.addActionListener(listener);

        //7.把5個按鈕添加到p2中
        p2.add(b1);
        p2.add(b2);
        p2.add(b3);
        p2.add(b4);
        p2.add(b5);


        //8.把p1添加到frame的中間區域
        frame.add(p1);


        //9.把p2添加到frame的底部區域
        frame.add(p2,BorderLayout.SOUTH);

        //10設置frame最佳大小並可見
        frame.pack();
        frame.setVisible(true);
    }
}

BoxLayout

為了簡化開發,Swing 引入了 一個新的佈局管理器 : BoxLayout 。 BoxLayout 可以在垂直和 水平兩個方向上擺放 GUI 組件, BoxLayout 提供瞭如下一個簡單的構造器:

方法名稱 方法功能
BoxLayout(Container target, int axis) 指定創建基於 target 容器的 BoxLayout 佈局管理器,該佈局管理器里的組件按 axis 方向排列。其中 axis 有 BoxLayout.X_AXIS( 橫向)和 BoxLayout.Y _AXIS (縱向〉兩個方向。

案例1:

​ 使用Frame和BoxLayout完成下圖效果:

演示代碼1:

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

public class BoxLayoutDemo1 {

    public static void main(String[] args) {

        //1.創建Frame對象
        Frame frame = new Frame("這裡測試BoxLayout");
        //2.創建BoxLayout佈局管理器,並指定容器為上面的frame對象,指定組件排列方向為縱向
        BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);
        frame.setLayout(boxLayout);

        //3.往frame對象中添加兩個按鈕
        frame.add(new Button("按鈕1"));
        frame.add(new Button("按鈕2"));


        //4.設置frame最佳大小,並可見
        frame.pack();
        frame.setVisible(true);
    }
}

在java.swing包中,提供了一個新的容器Box,該容器的預設佈局管理器就是BoxLayout,大多數情況下,使用Box容器去容納多個GUI組件,然後再把Box容器作為一個組件,添加到其他的容器中,從而形成整體視窗佈局。

方法名稱 方法功能
static Box createHorizontalBox() 創建一個水平排列組件的 Box 容器 。
static Box createVerticalBox() 創建一個垂直排列組件的 Box 容器 。

案例2:

​ 使用Frame和Box,完成下圖效果:

演示代碼2:

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

public class BoxLayoutDemo2 {

    public static void main(String[] args) {

        //1.創建Frame對象
        Frame frame = new Frame("這裡測試BoxLayout");

        //2.創建一個橫向的Box,並添加兩個按鈕
        Box hBox = Box.createHorizontalBox();
        hBox.add(new Button("水平按鈕一"));
        hBox.add(new Button("水平按鈕二"));

        //3.創建一個縱向的Box,並添加兩個按鈕
        Box vBox = Box.createVerticalBox();
        vBox.add(new Button("垂直按鈕一"));
        vBox.add(new Button("垂直按鈕二"));

        //4.把box容器添加到frame容器中
        frame.add(hBox,BorderLayout.NORTH);
        frame.add(vBox);


        //5.設置frame最佳大小並可見

        frame.pack();
        frame.setVisible(true);

    }
}

通過之前的兩個BoxLayout演示,我們會發現,被它管理的容器中的組件之間是沒有間隔的,不是特別的美觀,但之前學習的幾種佈局,組件之間都會有一些間距,那使用BoxLayout如何給組件設置間距呢?

其實很簡單,我們只需要在原有的組件需要間隔的地方,添加間隔即可,而每個間隔可以是一個組件,只不過該組件沒有內容,僅僅起到一種分隔的作用。

Box類中,提供了5個方便的靜態方法來生成這些間隔組件:

方法名稱 方法功能
static Component createHorizontalGlue() 創建一條水平 Glue (可在兩個方向上同時拉伸的間距)
static Component createVerticalGlue() 創建一條垂直 Glue (可在兩個方向上同時拉伸的間距)
static Component createHorizontalStrut(int width) 創建一條指定寬度(寬度固定了,不能拉伸)的水平Strut (可在垂直方向上拉伸的間距)
static Component createVerticalStrut(int height) 創建一條指定高度(高度固定了,不能拉伸)的垂直Strut (可在水平方向上拉伸的間距)

案例3:

使用Frame和Box,完成下圖效果:

演示代碼3:

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

public class BoxLayoutDemo3 {

    public static void main(String[] args) {
        //1.創建Frame對象
        Frame frame = new Frame("這裡測試BoxLayout");

        //2.創建一個橫向的Box,並添加兩個按鈕
        Box hBox = Box.createHorizontalBox();
        hBox.add(new Button("水平按鈕一"));
        hBox.add(Box.createHorizontalGlue());//兩個方向都可以拉伸的間隔
        hBox.add(new Button("水平按鈕二"));
        hBox.add(Box.createHorizontalStrut(10));//水平間隔固定,垂直間方向可以拉伸
        hBox.add(new Button("水平按鈕3"));



        //3.創建一個縱向的Box,並添加兩個按鈕
        Box vBox = Box.createVerticalBox();
        vBox.add(new Button("垂直按鈕一"));
        vBox.add(Box.createVerticalGlue());//兩個方向都可以拉伸的間隔
        vBox.add(new Button("垂直按鈕二"));
        vBox.add(Box.createVerticalStrut(10));//垂直間隔固定,水平方向可以拉伸
        vBox.add(new Button("垂直按鈕三"));


        //4.把box容器添加到frame容器中
        frame.add(hBox, BorderLayout.NORTH);
        frame.add(vBox);


        //5.設置frame最佳大小並可見

        frame.pack();
        frame.setVisible(true);
    }
}

個人博客本文地址:https://kohler19.gitee.io/2022/04/02/java-GUI1/
微信文章地址:https://mp.weixin.qq.com/s/jnkRVCcsiH9WA1W5V_ibBg

個人博客:https://kohler19.gitee.io/
歡迎關註公眾號愚生淺末

歡迎關註我的公眾號,共同學習


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前面幾篇博客,說了很多dubbo服務提供者相關的流程; 複習一下:首先服務提供者去暴露服務介面數據到註冊中心,然後本地啟動netty服務端監聽是否有消費者的請求,現在我們可以看看消費者端是怎麼從註冊中心獲取指定的介面信息, 然後訪問netty服務端,就行了; 提前須知:要提前瞭解spring的ioc ...
  • 假期玩嗨了吧,我給你準備了六個小游戲,有膽子來玩一玩嗎?我自己是玩了很多遍的,所以想讓大家一起玩,獨樂樂不如眾樂樂。代碼放在下麵。 1、小恐龍 玩法:上下控制起跳躲避 源碼分享: Python學習交流Q群:906715085### import cfg import sys import rando ...
  • 又到每日分享Python小技巧的時候了,我真是太開心了。今天給大家分享的是模擬太陽系行星運轉。聽起來就很不錯,效果出來的時候也是很不錯的,讓我們一起期待。 1、準備材料 首先我們需要準備這樣一些材料 宇宙背景圖 背景透明的行星圖 2:編寫代碼 代碼分塊詳解 導入需要的模塊 ###Python學習交流 ...
  • 最近我看好多人的朋友圈都流行發九宮格照片,別人都能擁有,碼農必須有。當然,我們要比其他人更為高調,我們就用Python來對圖片進行處理,這肯定能秀翻你的朋友圈。廢話不說,開乾。 一、圖片導入與信息查看 在對圖像進行處理之前,我們首先需要載入出來一張圖片,我們以載入文件中存在的圖像為例子,載入圖片並查 ...
  • 繼承 繼承1 繼承的好處2 繼承的細節3 如果父類和子類都有同一個屬性(比如name)那麼查找時遵循以下原則4 this和super區分 1 繼承的好處 代碼的復用性提高了 代碼的擴展性和維護性提高了 2 繼承的細節 子類繼承了所有的屬性和方法,非私有的屬性和方法可以在子類直接訪問,私有的屬性pri ...
  • 《零基礎學Java》 事件監聽器 為按鈕等添加事件監聽器,事件監聽器的作用是在用戶單擊按鈕時,設置窗體要實現的功能。 動作事件監聽器 動作事件監聽器(AbstractAction)監聽器是Swing中比較常用的事件監聽器,很多最近的動作都會使用它監聽(比如:按鈕被單擊)。 動作事件監聽器 動作事件監 ...
  • 最近實現了一個多端登錄的Spring Security組件,用起來非常絲滑,開箱即用,可插拔,而且靈活性非常強。我覺得能滿足大部分場景的需要。目前完成了手機號驗證碼和微信小程式兩種自定義登錄,加上預設的Form登錄,一共三種,現在開源分享給大家,接下來簡單介紹一下這個插件包。 DSL配置風格 切入正 ...
  • 目錄 一.簡介 二.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 OpenGL (ES) 學習路 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...