1. 程式人生 > >java-swing-佈局

java-swing-佈局

萬般皆苦,唯有自渡。

佈局概念

  • 概念:元件在容器(比如JFrame)中的位置和大小是由佈局管理器(layout mnager)來決定的。所有的容器都會使用一個佈局管理器,通過它來自動進行元件的佈局管理。
  • 種類:java共提供了五種佈局管理器:流式佈局管理器(FlowLayout)、邊界佈局管理器(BorderLayout)、網格佈局管理器(GridLayout)、卡片佈局管理器(CardLayout)、網格包佈局管理器(GridBagLayout)。其中前三種是最常見的佈局管理器。
  • 將元件加入到容器中之前,必須建立容器的佈局管理器,如果沒有指定佈局管理器,將使用預設的佈局管理器。:對於面板,預設為FlowLayout;對於框架和視窗,預設為:BorderLayout。
  • 建立佈局管理器後,使用setLayout()使得容器和佈局關聯起來。

佈局介紹

順序佈局(FlowLayout)

  • 類FlowLayout是最簡單的佈局管理器,它排列元件的方式和圖書排版類似:從左到右排列,到達末尾後,進入下一行。
  • 預設情況下,如果呼叫建構函式FlowLayout()時,沒有提供任何引數,每一行的元件都會居中排列。要讓元件右對齊或者左對齊,必須將類變數FlowLayout.LEFT或FlowLayout.RIGHT作為唯一的引數傳遞給建構函式。

常用方法

構造方法
FlowLayout() 
          構造一個新的 FlowLayout,它是居中對齊的,預設的水平和垂直間隙是 5 個單位。 
FlowLayout(int align) 
          構造一個新的 FlowLayout,它具有指定的對齊方式,預設的水平和垂直間隙是 5 個單位。 
FlowLayout(int align, int hgap, int vgap) 
          建立一個新的流佈局管理器,它具有指定的對齊方式以及指定的水平和垂直間隙。 
普通方法
 void addLayoutComponent(String name, Component comp) 
          將指定的元件新增到佈局中。 
 int getAlignment() 
          獲取此佈局的對齊方式。 
 boolean getAlignOnBaseline() 
          如果元件將沿其基線垂直對齊,則返回 true。 
 int getHgap() 
          獲取元件之間以及元件與 Container 的邊之間的水平間隙。 
 int getVgap() 
          獲取元件之間以及元件與 Container 的邊之間的垂直間隙。 
 void layoutContainer(Container target) 
          佈置該容器。 
 Dimension minimumLayoutSize(Container target) 
          返回需要佈置 visible 元件的最小維數,該元件包含在指定的目標容器中。 
 Dimension preferredLayoutSize(Container target) 
          給出指定目標容器中的 visible 元件,返回此佈局的首選維數。 
 void removeLayoutComponent(Component comp) 
          從佈局中移除指定的元件。 
 void setAlignment(int align) 
          設定此佈局的對齊方式。 
 void setAlignOnBaseline(boolean alignOnBaseline) 
          設定元件是否應該沿著其基線垂直對齊。 
 void setHgap(int hgap) 
          設定元件之間以及元件與 Container 的邊之間的水平間隙。 
 void setVgap(int vgap) 
          設定元件之間以及元件與 Container 的邊之間的垂直間隙。 

案例

package SwingDemo;

import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class swingDemo {
	public static void main(String[] args) {
	JFrame mainFrame = new JFrame("測試介面");
	     mainFrame.setSize(300, 300);
		 JPanel panel = new JPanel();
        JButton btn[]=new JButton[12];
       panel.setLayout(new FlowLayout(FlowLayout.LEFT));
       
        for(int i=0;i<10;i++){
        	btn[i] = new JButton("button"+i);
        	btn[i].setPreferredSize(new Dimension(50+5*i, 30+5*i));
        	//設定按鈕大小,在已經有佈局的情況下,setSize()是失效的。
        	panel.add(btn[i]);
        } 
		 mainFrame.setContentPane(panel);
		 mainFrame.setVisible(true);
	}
}

執行結果

邊界佈局管理器(BorderLayout)

  • 邊框佈局是使用類BorderLayout建立的,它將容器分為5部分:北、南、東、西和中央。
  • 在邊框佈局中,位於四個羅盤方位的元件將根據其需要佔據相應的空間,餘下的空間將屬於中央區域。通常,中央是一個大元件,四周是四個小元件。

方法概述

構造方法
BorderLayout() 
          構造一個元件之間沒有間距的新邊框佈局。 
BorderLayout(int hgap, int vgap) 
          構造一個具有指定元件間距的邊框佈局。 
普通方法
 void addLayoutComponent(Component comp, Object constraints) 
          使用指定的約束物件將指定元件新增到佈局中。 
 int getHgap() 
          返回元件之間的水平間距。 
 float getLayoutAlignmentX(Container parent) 
          返回沿 x 軸的對齊方式。 
 float getLayoutAlignmentY(Container parent) 
          返回沿 y 軸的對齊方式。 
 int getVgap() 
          返回元件之間的垂直間距。 
 void invalidateLayout(Container target) 
          使佈局無效,指示如果佈局管理器快取了資訊,則應該將其丟棄。 
 void layoutContainer(Container target) 
          使用此邊框佈局對容器引數進行佈局。 
 Dimension maximumLayoutSize(Container target) 
          在給出指定目標容器中的元件的前提下,返回此佈局的最大尺寸。 
 Dimension minimumLayoutSize(Container target) 
          使用此佈局管理器確定 target 容器的最小大小。 
 Dimension preferredLayoutSize(Container target) 
          基於容器中的元件,使用此佈局管理器確定 target 容器的首選大小。 
 void removeLayoutComponent(Component comp) 
          從此邊框佈局中移除指定元件。 
 void setHgap(int hgap) 
          設定元件之間的水平間距。 
 void setVgap(int vgap) 
          設定元件之間的垂直間距 

案例

package SwingDemo;

import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class swingDemo {
	public static void main(String[] args) {
	JFrame mainFrame = new JFrame("測試介面");
	     mainFrame.setSize(300, 300);
		 JPanel panel = new JPanel();
        JButton btn[]=new JButton[5];
       panel.setLayout(new BorderLayout(5,10));
       String dir[] =new String[]{"North","South","East","West","Center"};
        for(int i=0;i<5;i++){
        	btn[i] = new JButton("button"+i);
        	panel.add(btn[i],dir[i]);
        } 
		 mainFrame.setContentPane(panel);
		 mainFrame.setVisible(true);
	}
}

執行結果

網格佈局(GridLayout)

  • 網格佈局管理器將元件放置到由行和列組成的網格中。首先元件被加入到網格的第一行,並從最左邊的網格開始,依次向右排列。第一行的單元格排滿後,接下來的元件將加入到第二行最左邊的單元格中(如果有第二行)。
  • 方法將行數和列數都設定為非零值時,指定的列數將被忽略。列數通過指定的行數和佈局中的元件總數來確定。
構造方法
GridLayout() 
          建立具有預設值的網格佈局,即每個元件佔據一行一列。 
GridLayout(int rows, int cols) 
          建立具有指定行數和列數的網格佈局。 
GridLayout(int rows, int cols, int hgap, int vgap) 
          建立具有指定行數和列數的網格佈局。 
普通方法概述
void addLayoutComponent(String name, Component comp) 
          將具有指定名稱的指定元件新增到佈局。 
 int getColumns() 
          獲取此佈局中的列數。 
 int getHgap() 
          獲取元件之間的水平間距。 
 int getRows() 
          獲取此佈局中的行數。 
 int getVgap() 
          獲取元件之間的垂直間距。 
 void layoutContainer(Container parent) 
          使用此佈局佈置指定容器。 
 Dimension minimumLayoutSize(Container parent) 
          使用此網路佈局確定最小大小的容器引數。 
 Dimension preferredLayoutSize(Container parent) 
          使用此網格佈局確定容器引數的首選大小。 
 void removeLayoutComponent(Component comp) 
          從佈局移除指定元件。 
 void setColumns(int cols) 
          將此佈局中的列數設定為指定值。 
 void setHgap(int hgap) 
          將元件之間的水平間距設定為指定值。 
 void setRows(int rows) 
          將此佈局中的行數設定為指定值。 
 void setVgap(int vgap) 
          將元件之間的垂直間距設定為指定值。  

案例

package SwingDemo;

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class swingDemo {
	public static void main(String[] args) {
	JFrame mainFrame = new JFrame("測試介面");
	     mainFrame.setSize(300, 300);
		 JPanel panel = new JPanel();
        JButton btn[]=new JButton[39];
       panel.setLayout(new GridLayout(10,11));
       //指定的列數將被忽略。列數通過指定的行數和佈局中的元件總數來確定。
        for(int i=0;i<39;i++){
        	btn[i] = new JButton(""+i);
        	panel.add(btn[i]);
        } 
		 mainFrame.setContentPane(panel);
		 mainFrame.setVisible(true);
	}
}

執行結果

卡片佈局(CardLayout)

  • 對於選項卡這個概念大家可能不會陌生,就是在一個視窗中可以切換顯示多頁不同的內容,但同一時間只能是其中的某一頁可見的,這樣的一個個的頁面就是選項卡。
  • CardLayout就是類似的這樣一個佈局管理器,它能夠讓多個元件共享同一個顯示空間,共享空間的元件之間的關係就像重疊在一起的一幅撲克牌,元件重疊在一起,初始時顯示該空間中第一個元件,通過CardLayout類提供的方法可以切換該空間中顯示的元件。

方法概述

構造方法
CardLayout() 
          建立一個間距大小為 0 的新卡片佈局。 
CardLayout(int hgap, int vgap) 
          建立一個具有指定水平間距和垂直間距的新卡片佈局。 
普通方法概述
 void addLayoutComponent(Component comp, Object constraints) 
          將指定的元件新增到此卡片佈局的內部名稱表。 
 void first(Container parent) 
          翻轉到容器的第一張卡片。 
 int getHgap() 
          獲取元件之間的水平間距。 
 int getVgap() 
          獲取元件之間的垂直間距。 
 void invalidateLayout(Container target) 
          使佈局無效,指示如果佈局管理器快取了資訊,則應該將其丟棄。 
 void last(Container parent) 
          翻轉到容器的最後一張卡片。 
 void layoutContainer(Container parent) 
          使用此卡片佈局佈置指定的容器。 
 void next(Container parent) 
          翻轉到指定容器的下一張卡片。 
 void previous(Container parent) 
          翻轉到指定容器的前一張卡片。 
 void removeLayoutComponent(Component comp) 
          從佈局中移除指定的元件。 
 void setHgap(int hgap) 
          設定元件之間的水平間距。 
 void setVgap(int vgap) 
          設定元件之間的垂直間距。 
 void show(Container parent, String name) 
          翻轉到使用 addLayoutComponent 新增到此佈局的具有指定 name 的元件。

案例

package SwingDemo;

import java.awt.CardLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class swingDemo {
	public static void main(String[] args) {
	JFrame mainFrame = new JFrame("測試介面");
	     mainFrame.setSize(300, 300);
		 JPanel panel = new JPanel();
		 CardLayout cdLayout =new CardLayout();
       panel.setLayout(cdLayout);
       JPanel first =new JPanel();//第一個卡片
       first.add(new JButton("第一個卡片"));//卡片裡的內容
       panel.add(first);//將卡片加入到框架上的面板上
       JPanel center = new JPanel();
       center.add(new JButton("中間的卡片"));
       panel.add(center);
       JPanel last = new JPanel();
       last.add(new JButton("最後的卡片"));
       panel.add(last);
       mainFrame.setContentPane(panel);
		 mainFrame.setVisible(true);
       while(true){
    	   try {
			Thread.sleep(1000);//暫停1s
			cdLayout.next(panel);//切換到下一個卡片
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       }
       
		 
	}
}

執行結果

網格袋佈局(GridBagLayout)

  • 網格袋佈局是對網格佈局的一種擴充套件,相對於網格佈局:
    (1):元件可佔據網格中的多個單元格
    (2):不同行和列的比例不必相同
    (3):單元格中的元件可以以不同的方式排列

  • 要建立網格袋佈局,可以使用GridBagLayout類和助手類GridBagConstraints。GridBagLayout是佈局管理器,GridBagConstraints用於定義要放置到單元格中的每個元件的屬性-包括佈局、大小、對齊方式等。

GridBagLayout方法

構造方法
GridBagLayout() 
          建立網格包佈局管理器。
普通方法
 void setConstraints(Component comp, GridBagConstraints constraints) 
          設定此佈局中指定元件的約束條件。 
 void addLayoutComponent(Component comp, Object constraints) 
          使用指定 constraints 物件將指定元件新增到佈局中。 
 GridBagConstraints getConstraints(Component comp) 
          獲取指定元件的約束。 
 void invalidateLayout(Container target) 
          使佈局失效,指示如果佈局管理器快取了資訊,則應該將其丟棄。 
 void layoutContainer(Container parent) 
          使用此網格包佈局佈置指定容器。 
 Point location(int x, int y) 
          確定在佈局網格中哪個單元包含由 (x, y) 指定的點。 
protected  GridBagConstraints lookupConstraints(Component comp) 
          檢索指定元件的約束。 
 void removeLayoutComponent(Component comp) 
          從此佈局移除指定元件。 

GridBagConstraints的方法

 int gridheight 
          指定在元件顯示區域的一列中的單元格數。 
 int gridwidth 
          指定元件顯示區域的某一行中的單元格數。 
 int gridx 
          指定包含元件的顯示區域開始邊的單元格,其中行的第一個單元格為 gridx=0。 
 int gridy 
          指定位於元件顯示區域的頂部的單元格,其中最上邊的單元格為 gridy=0。 
 double weightx 
          指定如何分佈額外的水平空間。 
 double weighty 
          指定如何分佈額外的垂直空間。 
int fill 
       元件完全填充單元格的方式
            NONE:不調整元件大小。 //預設情況,這是不填充
			HORIZONTAL:加寬元件,使它在水平方向上填滿其顯示區域,但是不改變高度。 
			VERTICAL:加高元件,使它在垂直方向上填滿其顯示區域,但是不改變寬度。 
			BOTH:使元件完全填滿其顯示區域。 
 int anchor 
          當元件不完全填充單元格時,元件應該放在單元格哪個位置 
          絕對值有:CENTER、NORTH、NORTHEAST、EAST、SOUTHEAST、
          SOUTH、SOUTHWEST、WEST 和 NORTHWEST。

建立網格袋佈局的步驟:
(1):建立一個GridBagLayout物件,並將其指定為當前的佈局管理器。
(2):建立一個GridBagConstraints例項
(3):設定元件的約束條件
(4):將元件及其約束條件告訴佈局管理器
(5):將元件加入到容器中。

使用 步驟例項

package SwingDemo;

import java.awt.CardLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class swingDemo {
	public static void main(String[] args) {
	JFrame mainFrame = new JFrame("測試介面");
	     mainFrame.setSize(300, 300);
		 JPanel panel = new JPanel();
	    GridBagLayout gbLayout =new GridBagLayout();
	    GridBagConstraints gbBagConstraints=new GridBagConstraints();
	    panel.setLayout(gbLayout);
	    
	    //要新增的元件
	    JButton btn1 = new JButton("按鈕");
	    
	    //設定元件的約束條件
	    gbBagConstraints.gridx =0;
	    gbBagConstraints.gridy=0;
	    gbBagConstraints.gridwidth=1;
	    gbBagConstraints.gridheight=1;
	    gbBagConstraints.weightx=30;
	    gbBagConstraints.weighty=30;
	    gbBagConstraints.fill = GridBagConstraints.NONE;
	    gbBagConstraints.anchor = GridBagConstraints.CENTER;
	    
	    //將元件及約束條件告訴佈局管理器
	    gbLayout.setConstraints(btn1, gbBagConstraints);
	   //將元件新增到面板上 
	    panel.add(btn1);
	    
       mainFrame.setContentPane(panel);
		 mainFrame.setVisible(true);
    
	}
}

為了減少設定約束條件時的輸入量,可以先定義一個助手方法

public static void buildConstraints(GridBagConstraints con,int gx,int gy,int gw,int gh,int wx,int wy){
		con.gridx = gx,//起始位置單元格
		con.gridy= gy;
		con.gridwidth=gw;//佔據的單元格數目
		con.gridheight=gh;
		con.weightx=wx;//所佔比例
		con.weighty=wy;
	}

案例程式碼

使用網格袋佈局時,首先應在紙上設計,確定每個元件的位置和大小

package SwingDemo;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SpringLayout.Constraints;

public class swingDemo {
	
	public static void buildConstraints(GridBagConstraints con,int gx,int gy,int gw,int gh,int wx,int wy){
		con.gridx = gx;
		con.gridy= gy;
		con.gridwidth=gw;
		con.gridheight=gh;
		con.weightx=wx;
		con.weighty=wy;
	}
	public static void main(String[] args) {
	JFrame mainFrame = new JFrame("測試介面");
	     mainFrame.setSize(290, 150);
		 JPanel panel = new JPanel();
	    GridBagLayout gbLayout =new GridBagLayout();
	    GridBagConstraints gbBagConstraints=new GridBagConstraints();
	    panel.setLayout(gbLayout);
	    
	    //新增name標籤
	   JLabel nameLb = new JLabel("Name",JLabel.LEFT);
       buildConstraints(gbBagConstraints, 0, 0, 1, 1, 10, 30);
       gbBagConstraints.fill = GridBagConstraints.NONE;
       gbBagConstraints.anchor=GridBagConstraints.EAST;
	  gbLayout.setConstraints(nameLb, gbBagConstraints);
	 panel.add(nameLb);
	 
	   //新增Password標籤
	   JLabel passwodbLb = new JLabel("Password",JLabel.LEFT);
       buildConstraints(gbBagConstraints, 0, 1, 1, 1, 0, 40);
       gbBagConstraints.fill = GridBagConstraints.NONE;
       gbBagConstraints.anchor=GridBagConstraints.EAST;
	  gbLayout.setConstraints(passwodbLb, gbBagConstraints);
	 panel.add(passwodbLb);
	 
	  //新增賬號輸入框
	 JTextField  nameTf = new JTextField();
	 buildConstraints(gbBagConstraints, 1, 0, 1, 1, 90, 0);
	    gbBagConstraints.fill = GridBagConstraints.HORIZONTAL;
	       gbBagConstraints.anchor=GridBagConstraints.EAST;
	 gbLayout.setConstraints(nameTf, gbBagConstraints);
	 panel.add(nameTf);
	 
	 //新增密碼輸入框
	 JPasswordField passwordPf = new JPasswordField();
	 buildConstraints(gbBagConstraints, 1, 1, 1, 1, 0, 0);
	    gbBagConstraints.fill = GridBagConstraints.HORIZONTAL;
	       gbBagConstraints.anchor=GridBagConstraints.EAST;
	 gbLayout.setConstraints(passwordPf, gbBagConstraints);
	 panel.add(passwordPf);
	 
	 //新增確認按鈕
	 JButton OkBtn = new JButton("OK");
	 buildConstraints(gbBagConstraints, 0, 2, 2, 1, 0, 20);
	   
	       gbBagConstraints.anchor=GridBagConstraints.CENTER;
	 gbLayout.setConstraints(OkBtn, gbBagConstraints);
	 panel.add(OkBtn);
	 
       mainFrame.setContentPane(panel);
		 mainFrame.setVisible(true);
    
	}
}

執行結果