
當視窗設定為 GridBagLayout 的排版方式後,視窗物件利用 add() 方法加入視窗元件時,必須額外提供 GridBagConstraints 類別 (class) 的參數 (parameter) ,因為實際的設定是由 GridBagConstraints 型態的物件 (object) 來完成的。
以下這些 GridBagConstraints 型態物件的屬性 (field) 是我們需要設定的
| gridx | 行數 |
| gridy | 列數 |
| gridwidth | 行寬 |
| gridheight | 列高 |
| weightx | 行權值 |
| weighty | 列權值 |
| fill | 填滿方式 |
| anchor | 定位點 |
直的為行 (column) ,橫的為列 (row) ,行與列的起始值都是 0 。例如,我們要在第 1 行,第 0 列放一個 JTextField ,佔用 1 列,跨 6 行,因此屬於該 JTextField 的 GridBagConstraints 型態物件的屬性 gridx 設定為 1 , gridy 為 0 , gridwidth 為 6 , gridheight 為 1 。
有關行權值與列權值部份,我們的範例中設定為 0 即可。
填滿方式有底下數種
| GridBagConstraints.BOTH | 垂直水平都填滿 |
| GridBagConstraints.VERTICAL | 垂直填滿 |
| GridBagConstraints.HORIZONTAL | 水平填滿 |
| GridBagConstraints.NONE | 不填滿 |
定位點也有底下數種
| GridBagConstraints.CENTER | 中央對齊 |
| GridBagConstraints.EAST | 向右對齊 |
| GridBagConstraints.SOUTHEAST | 右下對齊 |
| GridBagConstraints.SOUTH | 向下對齊 |
| GridBagConstraints.SOUTHWEST | 左下對齊 |
| GridBagConstraints.WEST | 向左對齊 |
| GridBagConstraints.NORTHWEST | 左上對齊 |
| GridBagConstraints.NORTH | 向上對齊 |
| GridBagConstraints.NORTHEAST | 右上對齊 |
填滿方式與定位點就是依需求來設定囉!好了,我們來看看實際的 EncryptorGUI.java 吧!
import java.awt.*;
import javax.swing.*;
public class EncryptorGUI {
private JFrame frame;
private String[] name;
public EncryptorGUI() {
frame = new JFrame();
String n[] = {"Input",
"Output",
"hint...",
"New",
"Load",
"Save",
"Encode",
"Decode",
"Clear",
"Copy"};
name = n;
}
public void run() {
frame.setSize(600, 160);
frame.setLayout(new GridBagLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel n0 = new JLabel(name[0]);
GridBagConstraints c0 = new GridBagConstraints();
c0.gridx = 0;
c0.gridy = 0;
c0.gridwidth = 1;
c0.gridheight = 1;
c0.weightx = 0;
c0.weighty = 0;
c0.fill = GridBagConstraints.NONE;
c0.anchor = GridBagConstraints.WEST;
frame.add(n0, c0);
JLabel n1 = new JLabel(name[1]);
GridBagConstraints c1 = new GridBagConstraints();
c1.gridx = 0;
c1.gridy = 1;
c1.gridwidth = 1;
c1.gridheight = 1;
c1.weightx = 0;
c1.weighty = 0;
c1.fill = GridBagConstraints.NONE;
c1.anchor = GridBagConstraints.WEST;
frame.add(n1, c1);
JLabel n2 = new JLabel(name[2]);
GridBagConstraints c2 = new GridBagConstraints();
c2.gridx = 0;
c2.gridy = 3;
c2.gridwidth = 7;
c2.gridheight = 1;
c2.weightx = 0;
c2.weighty = 0;
c2.fill = GridBagConstraints.BOTH;
c2.anchor = GridBagConstraints.WEST;
frame.add(n2, c2);
JTextField n3 = new JTextField();
GridBagConstraints c3 = new GridBagConstraints();
c3.gridx = 1;
c3.gridy = 0;
c3.gridwidth = 6;
c3.gridheight = 1;
c3.weightx = 0;
c3.weighty = 0;
c3.fill = GridBagConstraints.BOTH;
c3.anchor = GridBagConstraints.WEST;
frame.add(n3, c3);
JTextField n4 = new JTextField();
GridBagConstraints c4 = new GridBagConstraints();
c4.gridx = 1;
c4.gridy = 1;
c4.gridwidth = 6;
c4.gridheight = 1;
c4.weightx = 0;
c4.weighty = 0;
c4.fill = GridBagConstraints.BOTH;
c4.anchor = GridBagConstraints.WEST;
frame.add(n4, c4);
for (int i = 0; i < 7; i++) {
JButton n5 = new JButton(name[i + 3]);
GridBagConstraints c5 = new GridBagConstraints();
c5.gridx = i;
c5.gridy = 2;
c5.gridwidth = 1;
c5.gridheight = 1;
c5.weightx = 0;
c5.weighty = 0;
c5.fill = GridBagConstraints.BOTH;
c5.anchor = GridBagConstraints.CENTER;
frame.add(n5, c5);
}
frame.setVisible(true);
}
}
/* 《程式語言教學誌》的範例程式
http://pydoing.blogspot.com/
檔名:EncryptorGUI.java
功能:示範 Java 程式
作者:張凱慶
時間:西元 2011 年 4 月 */實際操作 EncryptorGUI 由 EncryptorGUIDemo.java 來進行
public class EncryptorGUIDemo {
public static void main(String[] args) {
EncryptorGUI gui = new EncryptorGUI();
gui.run();
}
}
/* 《程式語言教學誌》的範例程式
http://pydoing.blogspot.com/
檔名:EncryptorGUIDemo.java
功能:示範 Java 程式
作者:張凱慶
時間:西元 2011 年 4 月 */記得,兩個都是新類別檔案,所以各自都要先編譯,才可以執行

結果如下
是的,這就是我們要的 GUI 外觀了,不過除了按鈕都在同一列,所以可以用一個迴圈 (loop) 設定外,其他的視窗元件都得個別設定有點麻煩,可不可以簡單一點呢?可以的,但是我們得先把視窗元件的參考變數都放到 ArrayList 中!
| 中英文術語對照 | |
|---|---|
| 格子 | grid |
| 小工具 | widget |
| 類別 | class |
| 參數 | parameter |
| 物件 | object |
| 屬性 | field |
| 行 | column |
| 列 | row |
| 迴圈 | loop |
您可以繼續參考
GUI 篇
相關目錄
回 Java 入門指南
回 Java 教材目錄
回首頁
參考資料
The JavaTM Tutorials: Getting Started
The JavaTM Tutorials: Learning the Java Language
The JavaTM Tutorials: Essential Classes
The Java Language Specification, Third Edition
本文於 2013 年 1 月訂正
4 則留言:
請問#10~#20為何不能簡化為:
name = {...陣列內容 ?
感謝指教!
因為 name 先被宣告為屬性,所以要實際建立 name ,就要用 new 來建立,例如
name = new String[10];
name[0] = "Input";
//以下略
大括弧屬於陣列的字面常數,用法是宣告後直接建立陣列物件中的初值。這裡是在建構子中建立區域的字串物件 n 後,再把 n 的參考給 name ,相對用 new 而言算是較簡化的寫法。
再請教觀念問題:
1. 是否可把#5. 和#9. 合併為:public JFrame frame = new JFrame(); 然後放在#5 ?
2. 關於陣列,是否以下的a均相同?
(a) int[] a = {1,2};
(b) int a[] = {1,2};
(c) int a[];
a = new int[2];
a[0] = 1;
a[1] = 2;
(d) int a[] = new int[2];
a[0] = 1;
a[1] = 2;
(e) int a[];
a = new int[]{1,2};
(f) int[] a = new int[]{1,2};
(g) int a[];
int b[] = {1,2};
a = b;
以上是我參考下面的 (原來new是有省略用法的?)
http://mis.hwai.edu.tw/~kevin/MISProject/JAVAProject/chapter4/c4-2.htm
3. 您的程式是否屬於2.的(g)此類?
若是,那就可改寫為像2.的(e)那樣囉?
謝謝教導!
1. 可以,不過我們的目的是把屬性的初始化放在建構子中,因此採取以上寫法;
2. 只要通過編譯,也就是編譯器沒有挑出錯誤就是支援的寫法;
3. 是的,可以這樣改寫。
至於陣列的中括弧應統一放在型態名稱後或是識別字後,我這裡的 String n[] 應該改成 String[] n 比較一致。
張貼留言