2014年2月1日 星期六

JavaFX Grid Pane

Grid Pane

Grid Pane的類別為javafx.scene.layout.GridPane,類似於Java AWT的Grid Layout。

在Java AWT中,Grid Layout如同其名稱Grid (格子) 一般,首先需設定橫列 (Row) 與直行 (Column) 的數目,以此將容器分成數個大小相同的格子區域,物件置放的順序預設為由左至右、由上而下,直至填滿所定義的格子區域為止,但每一個格子只能置放一個物件,且物件不能跨數個格子置放,所配置的物件大小會因視窗或Java Applet大小而改變,將同時向垂直或水平方向放大或縮小 

JavaFX的Grid Pane較Java AWT的Grid Layout更為彈性,除了類似於Grid Layout以行列格子的方式置放物件之外,Grid Pane更引進HTML表格標籤的合併儲存格概念,可將物件跨數個格子置放,稱為Span。合併分為水平合併與垂直合併,分別由columnIndexrowIndexcolspanrowspan參數設定,前兩者用以設定開始合併的行 (Column) 與列 (Row) 的格子位置,後兩者則是設定合併水平或垂直方向的格子數目。

合併功能讓JavaFX的Grid Pane更類似於Java AWT的Grid Bag Layout。Grid Bag Layout將容器劃分成數個小單元 (Cell),而其所配置的物件,可自行定義其水平與垂直的加權 (Weight) 比例,藉以決定其所佔滿的單元多寡,因此在Grid Bag Layout中,各物件的大小不需一致,而且當容器改變大小時,也可依其所定義之加權決定其變更大小的幅度。

以水平合併為例,colspan參數會向右延伸合併水平方向的數個格子,又稱為合併行。例如下圖將第1行第1列與第2行第1列合併,則columnIndexrowIndex分別設定為0,代表自第1行第1列開始合併;而colspan則設定為2,代表自第1行第1列開始向右延伸合併兩個格子。
以垂直合併為例,rowspan參數會向下延伸合併垂直方向的數個格子,又稱為合併列。例如下圖將第1行第1列與第1行第2列合併,則columnIndexrowIndex分別設定為0,代表自第1行第1列開始合併;而rowspan則設定為2,代表自第1行第1列開始向下延伸合併兩個格子。
請參考以下範例示範如何以3行4列之Grid Pane配置按鈕物件,依序以add()方法將按鈕物件置於Grid Pane第columnIndex行第rowIndex列的格子區域中。

須注意的是,JavaFX的Grid Pane在設定行與列參數的順序上,剛好與Java AWT的Grid Layout相反,GridLayout類別的建構函式如下,為先設定列參數、再設定行參數:

    public GridLayout(int rows, int cols)

JavaFX的Grid Pane則為先設定行參數、再設定列參數:

    public void add(Node child, int columnIndex, int rowIndex)

對於習慣Grid Layout的讀者,初次使用可能會混淆,請特別注意。


// 設定GridPane
GridPane gridpane = new GridPane();

// 設定GridPane的對齊方式為水平與垂直方向均靠中央對齊
gridpane.setAlignment(Pos.CENTER);
gridpane.setHgap(10);
gridpane.setVgap(10);
gridpane.setPadding(new Insets(10, 10, 10, 10));

final int column = 3;  // 行數
final int row = 4;     // 列數

// 設定Button物件
for (int i=0; i<column; i++) {
  for (int j=0; j<row; j++) {
    button[i][j] = new Button("(" + j + ":" + i + ")");
    // 設定Button物件的最佳尺寸
    button[i][j].setPrefSize(60, 20);
        
    // 將Button物件置於GridPane第i行第j列之格子區域中
    gridpane.add(button[i][j], i, j);
  }
}
...


【執行結果】
請參考以下範例同樣示範如何以3行4列之Grid Pane配置按鈕物件,不同的是藉由設定colspanrowspan參數合併水平與垂直方向的數個格子區域,如下圖所示:
其中
  • (0, 0)自第1行第1列開始將第1行第1列與第2行第1列水平合併,則columnIndex, rowIndex, colspan, rowspan分別設定為0, 0, 2, 1。
  • (1, 1)自第2行第2列開始將第2行第2列與第3行第2列水平合併,則columnIndex, rowIndex, colspan, rowspan分別設定為1, 1, 2, 1。
  • (2, 0)自第1行第3列開始將第1行第3列與第1行第4列垂直合併,則columnIndex, rowIndex, colspan, rowspan分別設定為0, 2, 1, 2。
  • (2, 2)自第3行第3列開始將第3行第3列與第3行第4列垂直合併,則columnIndex, rowIndex, colspan, rowspan分別設定為2, 2, 1, 2。
此外,為讓範例更容易理解,並以setGridLinesVisible()方法顯示Grid Pane的格線。


// 設定GridPane
GridPane gridpane = new GridPane();

// 設定GridPane的對齊方式為水平與垂直方向均靠中央對齊
gridpane.setAlignment(Pos.CENTER);
gridpane.setHgap(10);
gridpane.setVgap(10);
gridpane.setPadding(new Insets(10, 10, 10, 10));

// 顯示Grid Pane的格線
gridpane.setGridLinesVisible(true);

final int column = 3;  // 行數
final int row = 4;     // 列數

// 設定Button物件
Button button[][] = new Button[column][row];

button[0][0] = new Button("(" + 0 + ":" + 0 + ")");
button[0][0].setPrefSize(130, 20);
// Start at (0, 0) and colspan = 2
gridpane.add(button[0][0], 0, 0, 2, 1);

button[2][0] = new Button("(" + 0 + ":" + 2 + ")");
button[2][0].setPrefSize(60, 20);
// Start at (0, 2)
gridpane.add(button[2][0], 2, 0);

button[0][1] = new Button("(" + 1 + ":" + 0 + ")");
button[0][1].setPrefSize(60, 20);
// Start at (1, 0)
gridpane.add(button[0][1], 0, 1);

button[1][1] = new Button("(" + 1 + ":" + 1 + ")");
button[1][1].setPrefSize(130, 20);
// Start at (1, 1) and colspan = 2
gridpane.add(button[1][1], 1, 1, 2, 1);

button[0][2] = new Button("(" + 2 + ":" + 0 + ")");
button[0][2].setPrefSize(60, 50);
// Start at (2, 0) and rowspan = 2
gridpane.add(button[0][2], 0, 2, 1, 2);

button[1][2] = new Button("(" + 2 + ":" + 1 + ")");
button[1][2].setPrefSize(60, 20);
// Start at (2, 1)
gridpane.add(button[1][2], 1, 2);

button[1][3] = new Button("(" + 3 + ":" + 1 + ")");
button[1][3].setPrefSize(60, 20);
// Start at (3, 1)
gridpane.add(button[1][3], 1, 3);

button[2][2] = new Button("(" + 2 + ":" + 2 + ")");
button[2][2].setPrefSize(60, 20);
// Start at (2, 2) and rowspan = 2
gridpane.add(button[2][2], 2, 2, 1, 2);
...


【執行結果】
【參考資料】

[1] 黃嘉輝,深入研究JavaFX 2。
[2] 黃嘉輝,深入研究Java Swing。
[3] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[4] JavaFX:http://www.oracle.com/technetwork/java/javafx
[5] JavaFX 2.2 API Specification.
[6] Java Platform, Standard Edition 7 API Specification.

© Chia-Hui Huang

沒有留言:

張貼留言