實例化使用模板
GridBagLayout gbl = new GridBagLayout();
// gbl.columnWidths = new int[]{200,200,200}; // 用數組設置列
// gbl.rowHeights = new int[]{100,100,100,100,100}; // 用數組設置行GridBagConstraints gbc = new GridBagConstraints();/*** gridBagConstraints.fill* 當子組件比所在網格小時:* 設置 fill =* GridBagConstraints.NONE; 不拉伸, 是默認值* GridBagConstraints.HORIZONTAL; 水平填滿所在網格* GridBagConstraints.VERTICAL; 垂直填滿所在網格* GridBagConstraints.BOTH; 拉伸到所在網格大小,填滿所在網格, */gbc.fill = GridBagConstraints.NONE;
// gbc.fill = GridBagConstraints.BOTH ;/*** gridBagConstraints.anchor , `anchor`中文意思是: 錨(n), 拋錨(v)* 當子組件比所在網格小時:* 設置 anchor =* GridBagConstraints.CENTER; 位于水平和垂直的正中央,(默認值)* GridBagConstraints.EAST; 東* GridBagConstraints.SOUTH; 南* GridBagConstraints.WEST; 西* GridBagConstraints.NORTH; 北* GridBagConstraints.NORTHEAST;(東北,右上)* GridBagConstraints.SOUTHEAST;(東南,右下)* GridBagConstraints.SOUTHWEST;(西南,左上)* GridBagConstraints.NORTHWEST;(西北,左上)* 還有很多選項* 此屬性接受三種類型的值:相對于方向(orientation relative)、相對于基線(baseline relative)和絕對位置(absolute)。絕對位置值不依賴于其他因素,包括:CENTER(中心)、NORTH(北)、NORTHEAST(東北)、EAST(東)、SOUTHEAST(東南)、SOUTH(南)、SOUTHWEST(西南)、WEST(西)和NORTHWEST(西北)。
相對于方向的值依賴于容器的組件方向屬性,包括:PAGE_START(頁面開始)、PAGE_END(頁面結束)、LINE_START(行開始)、LINE_END(行結束)、FIRST_LINE_START(第一行開始)、FIRST_LINE_END(第一行結束)、LAST_LINE_START(最后一行開始)和LAST_LINE_END(最后一行結束)。
相對于基線的值依賴于基線位置,包括:BASELINE(基線)、BASELINE_LEADING(基線前導)、BASELINE_TRAILING(基線后尾)、ABOVE_BASELINE(基線之上)、ABOVE_BASELINE_LEADING(基線之上前導)、ABOVE_BASELINE_TRAILING(基線之上后尾)、BELOW_BASELINE(基線之下)、BELOW_BASELINE_LEADING(基線之下前導)和BELOW_BASELINE_TRAILING(基線之下后尾)。
默認值是CENTER,表示組件居中放置。*/gbc.anchor = GridBagConstraints.CENTER;
// gbc.anchor = GridBagConstraints.NORTH;gbc.gridx = -1; gbc.gridy = GridBagConstraints.RELATIVE; //網格的橫縱坐標,從0開始, -1是RELATIVE相對自動gbc.gridwidth = 1; gbc.gridheight = 1; //橫向或縱向站幾個網格,如同html的td的colspan和rowspangbc.ipadx = 0; gbc.ipady = 0; //增加子組件寬高, gbc.weightx = 0; gbc.weighty = 0; 才有效gbc.weightx = 0; gbc.weighty = 0; //值為浮點數, 功能有點像css的grid的fr , 不為0時
GridBagLayout
columnWidths
用int數組設置列的數量和寬度rowHeights
用int數組設置行的數量和寬度columnWeights
double數組, 默認是空,rowWeights
double數組, 默認是空,
columnWidths 和 rowHeights
三行三列
GridBagLayout gbl = new GridBagLayout(); frame.setLayout(gbl);
gbl.columnWidths=new int[]{200,200,200}; // 用數組設置列
gbl.rowHeights = new int[]{100,100,100}; // 用數組設置行
單行單列
GridBagLayout gbl = new GridBagLayout(); frame.setLayout(gbl);
gbl.columnWidths=new int[]{200}; // 用數組設置列
gbl.rowHeights = new int[]{100}; // 用數組設置行
columnWeights 和 rowWeights
columnWeights
columnWeights是一個double數組,它包含一組可以覆蓋已計算列權重的值。如果這個字段是非空的,那么在所有列的權重被計算之后,這些值將被應用到GridBag布局中。如果columnWeights數組中的某個元素的值大于對應列的權重,那么該列將被分配columnWeights數組中對應元素的值作為權重。然而,如果columnWeights數組的元素數量超過列的數量,多余的元素將被忽略,而不會導致創建更多的列。
/*** This field holds the overrides to the column weights.* If this field is non-{@code null} the values are* applied to the gridbag after all of the columns* weights have been calculated.* If {@code columnWeights[i] >} weight for column i, then* column i is assigned the weight in {@code columnWeights[i]}.* If {@code columnWeights} has more elements than the number* of columns, the excess elements are ignored - they do* not cause more columns to be created.** @serial*/
public double[] columnWeights;
此字段包含列權重的覆蓋。如果此字段非空,則值將在計算完所有列權重后應用于網格包。如果columnWeights[i] > column i的權重,則column i被分配columnWeights[i]中的權重。如果columnWeights的元素多于列數,則多余的元素將被忽略 - 它們不會導致創建更多的列。
rowWeights
rowWeights是一個double數組,它包含行權重的覆蓋值。如果該字段不為空,則在計算完所有行權重后,這些值將被應用到網格包中。如果rowWeights[i]的值大于第i行的權重,則第i行將被分配rowWeights[i]中的權重。如果rowWeights的元素數量超過行數,多余的元素將被忽略,并且不會導致創建更多的行。
/*** This field holds the overrides to the row weights.* If this field is non-{@code null} the values are* applied to the gridbag after all of the rows* weights have been calculated.* If {@code rowWeights[i] > } weight for row i, then* row i is assigned the weight in {@code rowWeights[i]}.* If {@code rowWeights} has more elements than the number* of rows, the excess elements are ignored - they do* not cause more rows to be created.** @serial*/
這個字段持有對行權重的覆蓋。如果這個字段非空,那么這些值將在所有行權重被計算后應用于網格包(GridBag)。如果rowWeights[i] > i行的權重,那么i行將分配rowWeights[i]中的權重。如果rowWeights的元素數量超過行數,多余的元素將被忽略,它們不會導致創建更多的行。
public double[] rowWeights;
GridBagConstraint
GridBagConstraints
類包含許多用于定義這些約束的字段和方法。以下是一些常用的字段:
gridx
和gridy
:指定組件在網格中的位置。gridwidth
和gridheight
:指定組件跨越的網格單元數量。weightx
和weighty
:指定組件在其行或列中的額外空間分配比例。anchor
:指定組件在其網格單元中的對齊方式。fill
:指定組件在其網格單元中的填充方式。insets
:指定組件的邊緣間距。
GridBagConstraints源碼的無參構造方法,可看出默認值
public GridBagConstraints () {gridx = RELATIVE; //從0開始第幾列; 默認RELATIVE=-1,表示add時自動加列gridy = RELATIVE; //從0開始第幾行; 默認RELATIVE=-1,表示add時自動加行gridwidth = 1; //如同colspan,橫跨幾列gridheight = 1; //如共同rowspan,豎跨幾行weightx = 0; //浮點數, 功能有點像css的grid的frweighty = 0; //浮點數, 功能有點像css的grid的franchor = CENTER;fill = NONE;insets = new Insets(0, 0, 0, 0);ipadx = 0; // 增加子件寬度, weightx=0時才有用ipady = 0; // 增加子件高度, weighty=0時才有用}
GridBagConstraints源碼的設參構造方法
public GridBagConstraints(int gridx, int gridy,int gridwidth, int gridheight,double weightx, double weighty,int anchor, int fill,Insets insets, int ipadx, int ipady) {this.gridx = gridx;this.gridy = gridy;this.gridwidth = gridwidth;this.gridheight = gridheight;this.fill = fill;this.ipadx = ipadx;this.ipady = ipady;this.insets = insets;this.anchor = anchor;this.weightx = weightx;this.weighty = weighty;}
anchor
anchor
中文意思是: 錨(n), 拋錨(v)
anchor
屬性決定了組件在其單元格中的位置。例如,如果 anchor
被設置為 GridBagConstraints.WEST
,組件將被左對齊。
以下是一些可能的 anchor
值:
GridBagConstraints.CENTER
:將組件居中在其單元格中(默認)。GridBagConstraints.NORTH
:將組件與其單元格的頂部對齊。GridBagConstraints.SOUTH
:將組件與其單元格的底部對齊。GridBagConstraints.EAST
:將組件與其單元格的右側對齊。GridBagConstraints.WEST
:將組件與其單元格的左側對齊。GridBagConstraints.NORTHWEST
:將組件與其單元格的左上角對齊。GridBagConstraints.NORTHEAST
:將組件與其單元格的右上角對齊。GridBagConstraints.SOUTHWEST
:將組件與其單元格的左下角對齊。GridBagConstraints.SOUTHEAST
:將組件與其單元格的右下角對齊。
還有更多取值,如與基線對齊相關的: GridBagConstraints.BASELINE
, GridBagConstraints.BASELINE_LEADING
, 和 GridBagConstraints.BASELINE_TRAILING
等值
anchor還有更多的取值,
此屬性接受三種類型的值:相對于方向(orientation relative)、相對于基線(baseline relative)和絕對位置(absolute)。
-
絕對位置值不依賴于其他因素,包括:CENTER(中心)(默認值)、NORTH(北)、NORTHEAST(東北)、EAST(東)、SOUTHEAST(東南)、SOUTH(南)、SOUTHWEST(西南)、WEST(西)和NORTHWEST(西北)。
-
相對于方向的值依賴于容器的組件方向屬性,包括:PAGE_START(頁面開始)、PAGE_END(頁面結束)、LINE_START(行開始)、LINE_END(行結束)、FIRST_LINE_START(第一行開始)、FIRST_LINE_END(第一行結束)、LAST_LINE_START(最后一行開始)和LAST_LINE_END(最后一行結束)。
-
相對于基線的值依賴于基線位置,包括:BASELINE(基線)、BASELINE_LEADING(基線前導)、BASELINE_TRAILING(基線后尾)、ABOVE_BASELINE(基線之上)、ABOVE_BASELINE_LEADING(基線之上前導)、ABOVE_BASELINE_TRAILING(基線之上后尾)、BELOW_BASELINE(基線之下)、BELOW_BASELINE_LEADING(基線之下前導)和BELOW_BASELINE_TRAILING(基線之下后尾)。
默認值是 CENTER,表示組件居中放置。GridBagConstraints.CENTER
fill
這個字段用于當組件的顯示區域大于組件所請求的大小時。它決定了是否要調整組件的大小,以及如果要調整,該如何調整。
對于填充(fill)屬性,以下值是有效的:
? NONE:不調整組件的大小。(默認值)
? HORIZONTAL:使組件足夠寬,以水平填充其顯示區域,但不改變其高度。
? VERTICAL:使組件足夠高,以垂直填充其顯示區域,但不改變其寬度。
? BOTH:使組件完全填充其顯示區域。
默認值是NONE。這意味著,除非明確指定,否則組件的大小不會進行調整以適應其顯示區域。
weightx
和weighty
gbc.weightx ; gbc.weighty; 可實現css的grid的fr的效果
注意f下面代碼or循環中的gbc.weighty = gbc.weightx = r*c;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;public class T2311300901 {public static void main(String...arguments)throws Exception{JFrame frame = new JFrame(Thread.currentThread().getStackTrace()[1].getClassName());frame.setBounds(100, 100, 800, 600);frame.addWindowListener(new WindowAdapter() {@Override public void windowClosing(WindowEvent wev) {System.exit(100);}});GridBagLayout gbl = new GridBagLayout();
// gbl.columnWidths = new int[]{200,200,200}; // 用數組設置列
// gbl.rowHeights = new int[]{100,100,100,100,100}; // 用數組設置行GridBagConstraints gbc = new GridBagConstraints();gbc.fill = GridBagConstraints.BOTH;
// gbc.anchor = GridBagConstraints.EAST;gbc.gridwidth = 1; gbc.gridheight = 1; gbc.ipadx = 0; gbc.ipady = 0;gbc.weightx = 0; gbc.weighty = 0;JPanel panel = new JPanel(gbl); frame.getContentPane().add(panel);int xc=3 , yc=3;JButton jbtA2[][] = new JButton[yc][];for(int r=0;r<yc;r++) {jbtA2[r] = new JButton[xc];for(int c=0;c<xc;c++) {gbc.gridx=c;gbc.gridy=r;gbc.weighty = gbc.weightx = r*c;JButton jbt = new JButton("<html><div style='color:red;'>"+"R"+r+"C"+c+"</div></html>");
// gbl.setConstraints(jbt, gbc); panel.add(jbt); // 可用 panel.add(jbt, gbc); 取代//👆👇上下句效果一樣,二選一panel.add(jbt, gbc);}}frame.setVisible(true);}
}
用 GridBagLayout 和 GridBagConstraints 來居中
例1 , 單網格居中
import java.awt.*;
import java.awt.event.*;import javax.swing.*;public class GridBag居中 {static JFrame frame = new JFrame(Thread.currentThread().getStackTrace()[1].getClassName());static GridBagLayout frameGbl = new GridBagLayout();static GridBagConstraints frameGbc = new GridBagConstraints();static {frame.addWindowListener(new WindowAdapter() {@Override public void windowClosing(WindowEvent ev) {System.exit(0);}});frame.setBounds(100, 100, 800, 600);frame.setLayout(frameGbl);}static JButton jbt = new JButton("jbt001");static {GridBagLayout gbl = frameGbl; GridBagConstraints gbc = frameGbc;// 將布局設為一列一行, 如果不設定, 在只加入一個子組件時也會自動變為一列一行, 但是沒有高寬, 即便fill=BOTH,由于網格的高寬為0,子組件依然是原始大小gbl.columnWidths = new int[] {300}; // 網格寬度gbl.rowHeights = new int[] {100}; // 網格高度gbc.fill = GridBagConstraints.BOTH; // 橫縱拉伸為和網格一樣的寬高, 就可以用 columnWidths 和 rowHeights 來設定子組件的寬高frame.add(jbt, gbc);// 注意: 此時布局大小只是整個Button的大小,并不是容器的大小, 居中是因為容器的默認, 而不是 anchor 屬性默認值的作用}public static void main(String...arguments)throws Exception{frame.setVisible(true);}}
效果
關鍵代碼
// 將布局設為一列一行, 如果不設定, 在只加入一個子組件時也會自動變為一列一行, 但是沒有高寬, 即便fill=BOTH,由于網格的高寬為0,子組件依然是原始大小gbl.columnWidths = new int[] {300}; // 網格寬度gbl.rowHeights = new int[] {100}; // 網格高度gbc.fill = GridBagConstraints.BOTH; // 橫縱拉伸為和網格一樣的寬高, 就可以用 columnWidths 和 rowHeights 來設定子組件的寬高frame.add(jbt, gbc);// 注意: 此時布局大小只是整個Button的大小,并不是容器的大小, 居中是因為容器的默認, 而不是 anchor 屬性默認值的作用
還有一些屬性因為默認值就滿足要求,所以不用設置
注意: 此時布局大小只是整個Button的大小,并不是容器的大小, 居中是因為容器的默認, 而不是 anchor 屬性默認值的作用
例2 , 九網格居中
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;public class GridBag居中2 {static JFrame frame = new JFrame(Thread.currentThread().getStackTrace()[1].getClassName());static GridBagLayout frameGbl = new GridBagLayout();static GridBagConstraints frameGbc = new GridBagConstraints();static {frame.addWindowListener(new WindowAdapter() {@Override public void windowClosing(WindowEvent ev) {System.exit(0);}});frame.setBounds(100, 100, 800, 600);frame.setLayout(frameGbl);}static JButton jbt = new JButton("""<html><span style="font-size:30px; color:blue; ">按鈕1</span></html>""");static {GridBagLayout gbl = frameGbl; GridBagConstraints gbc = frameGbc;// 將布局設為一列一行, 如果不設定, 在只加入一個子組件時也會自動變為一列一行, 但是沒有高寬, 即便fill=BOTH,由于網格的高寬為0,子組件依然是原始大小gbl.columnWidths = new int[] {9999,300,9999}; // 網格寬度, 設置3列, 只要左右相等,就能居中,即便總數超過容器寬度gbl.rowHeights = new int[] {666,300,666}; // 網格高度, 設置3列, 只要左右相等,就能居中,即便總數超過容器高度gbc.fill = GridBagConstraints.BOTH; // 橫縱拉伸為和網格一樣的寬高, 就可以用 columnWidths 和 rowHeights 來設定子組件的寬高gbc.gridx=1; gbc.gridy=1; // 放到中間格(橫豎第二格),索引從0開始,所以第二格的索引號是1gbc.anchor = GridBagConstraints.WEST;frame.add(jbt, gbc);}public static void main(String...arguments)throws Exception{frame.setVisible(true);}
效果
關鍵代碼
// 將布局設為一列一行, 如果不設定, 在只加入一個子組件時也會自動變為一列一行, 但是沒有高寬, 即便fill=BOTH,由于網格的高寬為0,子組件依然是原始大小gbl.columnWidths = new int[] {9999,300,9999}; // 網格寬度, 設置3列, 只要左右相等,就能居中,即便總數超過容器寬度gbl.rowHeights = new int[] {666,300,666}; // 網格高度, 設置3列, 只要左右相等,就能居中,即便總數超過容器高度gbc.fill = GridBagConstraints.BOTH; // 橫縱拉伸為和網格一樣的寬高, 就可以用 columnWidths 和 rowHeights 來設定子組件的寬高gbc.gridx=1; gbc.gridy=1; // 放到中間格(橫豎第二格),索引從0開始,所以第二格的索引號是1gbc.anchor = GridBagConstraints.WEST;frame.add(jbt, gbc);
可以用邊緣網格控制中間網格的位置, 只居中時, 可以將左右上下網格的高寬設很大,只要左等于右,上等于下,就能居中,并且可以用中間網格的大小調整子組件的大小