當視窗設定為 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 比較一致。
張貼留言