原文位址http://download.oracle.com/javafx/2.0/layout/builtin_layouts.htm
在JavaFX應用中,當然可以通過指定UI元素的位置和大小屬性來手動布局。不過,更簡單的方法是使用布局窗格。JavaFX SDK提高了多種布局容器類(稱為窗格)來友善的建立和管理經典布局,如行、列、堆、拼貼等。由于視窗是可以改變大小的,是以布局窗格會根據其包含的結點自動修改位置和大小。
本文是JavaFX布局窗格的概覽,并為每個窗格提供了小例子。
邊框窗格BorderPane
BorderPane布局窗格提供了5塊放置結點的區域:頂部、底部、座部、右部、中部。
Figure 1-1 是能用該布局窗格建立的布局類型。區域可以是任意大小的,如果不需要某一塊,可以不定義。
Figure 1-1 Sample Border Pane
Description of "Figure 1-1 Sample Border Pane"邊框窗格對于經典布局很有用,像頂部的工具欄,底部的狀态欄,左邊的導航面闆,右邊的補充資訊,中間的工作區。
Example 1-1建立了一個每個區域是有色矩形的邊框窗格。
Example 1-1 Create a Border Pane
BorderPane layout = new BorderPane();
layout.setTop(new Rectangle(200, 50, Color.DARKCYAN));
layout.setBottom(new Rectangle(200, 50, Color.DARKCYAN));
layout.setCenter(new Rectangle(100, 100, Color.MEDIUMAQUAMARINE));
layout.setLeft(new Rectangle(50, 100, Color.DARKTURQUOISE));
layout.setRight(new Rectangle(50, 100, Color.DARKTURQUOISE));
水準盒子HBox
HBox
布局窗格提供了一種簡單的方法來把一些列結點放進單行裡面。
Figure 1-2是
一個HBox
窗格的例子。
Figure 1-2 Sample HBox Pane
Description of "Figure 1-2 Sample HBox Pane"Padding屬性用來設定結點和
HBox的邊緣間距離。
Spacing屬性用來設定結點間距離。style用來改變背景色。
Example 1-2建立了一個工具欄的
HBox
窗格,裡面有兩個按鈕。
Example 1-2 Create an HBox Pane
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10);
hbox.setStyle("-fx-background-color: #336699");
Button buttonCurrent = new Button("Current");
buttonCurrent.setPrefSize(100, 20);
Button buttonProjected = new Button("Projected");
buttonProjected.setPrefSize(100, 20);
hbox.getChildren().addAll(buttonCurrent, buttonProjected);
BorderPane border = new BorderPane();
border.setTop(hbox);
中的最後一行建立了一個邊框布局,并把
HBox加入到頂部區域。結果見
Figure 1-3 .
Figure 1-3 HBox Pane in a Border Pane
Description of "Figure 1-3 HBox Pane in a Border Pane"垂直盒子VBox
VBox
布局窗格和
HBox
布局很類似,差別僅僅是垂直盒子的結點是組織進一列中。
Figure 1-4是一個
VBox窗格的例子。
Figure 1-4 Sample VBox Pane
Description of "Figure 1-4 Sample VBox Pane"VBox的邊緣間距離。
Spacing屬性用來設定結點間距離。
Example 1-3建立了一個選項清單
VBox。
Example 1-3 Create a VBox Pane
VBox vbox = new VBox();
vbox.setPadding(new Insets(10, 10, 10, 10));
vbox.setSpacing(10);
Text title = new Text("Data");
title.setFont(Font.font("Amble CN", FontWeight.BOLD, 14));
vbox.getChildren().add(title);
Text options[] = new Text[] {
new Text(" Sales"),
new Text(" Marketing"),
new Text(" Distribution"),
new Text(" Costs")};
for (int i=0; i<4; i++) {
vbox.getChildren().add(options[i]);
}
border.setLeft(vbox); // Add to BorderPane from Example 1-2
中最後一行把
VBox窗格加入到了邊框布局中的左部。結果見
Figure 1-5 Figure 1-5 VBox Pane in a Border Pane
Description of "Figure 1-5 VBox Pane in a Border Pane"堆棧窗格StackPane
StackPane布局窗格把所有結點放進一個堆棧中,新結點都在前一個結點上面。該布局模式可以友善地
在形狀和圖檔上疊加文字或将多種簡單形狀組合成一個複雜形狀。
Figure 1-6是一個幫助圖示,是将一個問号放在了具有漸變背景的矩形上面。
Figure 1-6 Sample Stack Pane
Description of "Figure 1-6 Sample Stack Pane" Example 1-4為幫助圖示建立了堆棧窗格。
Example 1-4 Create a Stack Pane
StackPane stack = new StackPane();
Rectangle helpIcon = new Rectangle(35.0, 25.0);
helpIcon.setFill(new LinearGradient(0,0,0,1, true, CycleMethod.NO_CYCLE,
new Stop[]{
new Stop(0,Color.web("#4977A3")),
new Stop(0.5, Color.web("#B0C6DA")),
new Stop(1,Color.web("#9CB6CF")),}));
helpIcon.setStroke(Color.web("#D0E6FA"));
helpIcon.setArcHeight(3.5);
helpIcon.setArcWidth(3.5);
Text helpText = new Text("? ");
helpText.setFont(Font.font("Amble Cn", FontWeight.BOLD, 18));
helpText.setFill(Color.WHITE);
helpText.setStroke(Color.web("#7080A0"));
stack.getChildren().addAll(helpIcon, helpText);
stack.setAlignment(Pos.CENTER_RIGHT); // Right-justify nodes in stack
HBox.setHgrow(stack, Priority.ALWAYS); // Give stack any extra space
hbox.getChildren().add(stack); // Add to HBox from Example 1-2
的最後一行把堆棧窗格加入到了
HBox
中,并且讓它永遠在最右邊。結果見
Figure 1-7Figure 1-7 Stack Pane in an HBox Pane
Description of "Figure 1-7 Stack Pane in an HBox Pane"網格窗格GridPane
GridPane
布局窗格可以靈活的建立放置結點的行和列的網絡。結點可以放在任何網格細胞中,并且需要時還可以跨細胞。網格窗格用來建立表格或者是任何用行和列組織的布局。
Figure 1-8是一個包含一個圖示、小标題、文本和餅圖的網格窗格。在圖中,
gridLinesVisible
屬性用來設定顯示網格線以看出行和列。該屬性對于調試
GridPane
布局很有用。
Figure 1-8 Sample Grid Pane
Description of "Figure 1-8 Sample Grid Pane"Gap屬性來控制行和列直接的空間。padding屬性來控制結點和網格窗格邊緣的距離。
Example 1-5creates the grid pane shown in
Example 1-5 Create a Grid Pane
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(0, 0, 0, 10));
// Category in column 2, row 1
Text category = new Text("Sales:");
category.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
grid.add(category, 1, 0);
// Title in column 3, row 1
Text chartTitle = new Text("Current Year");
chartTitle.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
grid.add(chartTitle, 2, 0);
// Subtitle in columns 2-3, row 2
Text chartSubtitle = new Text("Goods and Services");
grid.add(chartSubtitle, 1, 1, 2, 1);
// House icon in column 1, rows 1-2
ImageView imageHouse = new ImageView(
new Image(LayoutSample.class.getResourceAsStream("graphics/house.png")));
grid.add(imageHouse, 0, 0, 1, 2);
// Left label in column 1 (bottom), row 3
Text goodsPercent = new Text("Goods\n80%");
GridPane.setValignment(goodsPercent, VPos.BOTTOM);
grid.add(goodsPercent, 0, 2);
// Chart in columns 2-3, row 3
ImageView imageChart = new ImageView(
new Image(LayoutSample.class.getResourceAsStream("graphics/piechart.png")));
grid.add(imageChart, 1, 2, 2, 1);
// Right label in column 4 (top), row 3
Text servicesPercent = new Text("Services\n20%");
GridPane.setValignment(servicesPercent, VPos.TOP);
grid.add(servicesPercent, 3, 2);
border.setCenter(grid); // Add to BorderPane from Example 1-2
的最後一行把網格布局放到了邊框布局的中間。結果見
Figure 1-9Figure 1-9 Grid Pane in a Border Pane
Description of "Figure 1-9 Grid Pane in a Border Pane"由于視窗大小的變化,網格成功的結點會根據布局限制重置大小。
流窗格FlowPane
FlowPane布局窗格中的結點會連續放置在窗格的邊界集中。結點可以垂直流向
(columns) 或水準流向(rows)。垂直流向窗格具有較高的分界線,水準流向窗格具有較寬的分界線。
Figure 1-10是一個使用了數字圖示的水準窗格例子。相反,垂直流向窗格中,第一列會包含1到4,第二列包含5到8。
Figure 1-10 Sample Horizontal Flow Pane
Description of "Figure 1-10 Sample Horizontal Flow Pane" Example 1-6建立了一些列圖示的水準流窗格。
Example 1-6 Create a Flow Pane
FlowPane flow = new FlowPane();
flow.setPadding(new Insets(5, 0, 5, 0));
flow.setVgap(4);
flow.setHgap(4);
flow.setPrefWrapLength(170); // preferred width allows for two columns
flow.setStyle("-fx-background-color: DAE6F3");
ImageView pages[] = new ImageView[8];
for (int i=0; i<8; i++) {
pages[i] = new ImageView(
new Image(LayoutSample.class.getResourceAsStream("graphics/chart_"+i+".png")));
flow.getChildren().add(pages[i]);
}
border.setRight(flow); // Add to BorderPane from Example 1-2
把流窗格放到了邊框窗格的右部。結果是
Figure 1-11Figure 1-11 Flow Pane in a Border Pane
Description of "Figure 1-11 Flow Pane in a Border Pane"瓦片窗格TilePane
瓦片窗格和流窗格很類似,
TilePane
布局窗格中的所有結點都大小相同,放在網格中。結點可以水準放置(in rows) 或垂直放置(in columns)。水準放置的瓦片在寬度寬度方向而垂直的在高度方向。
使用prefColumns和
prefRows屬性來設定瓦片窗格的首選大小。
Example 1-7 建立了一個水準瓦片窗格,其效果和
相同。
Example 1-7 Create a Tile Pane
TilePane tile = new TilePane();
tile.setPadding(new Insets(5, 0, 5, 0));
tile.setVgap(4);
tile.setHgap(4);
tile.setPrefColumns(2);
tile.setStyle("-fx-background-color: DAE6F3");
ImageView pages[] = new ImageView[8];
for (int i=0; i<8; i++) {
pages[i] = new ImageView(
new Image(LayoutSample.class.getResourceAsStream("graphics/chart_"+i+".png")));
tile.getChildren().add(pages[i]);
}
錨窗格AnchorPane
AnchorPane
布局窗格用來在窗格的上下左右中固定結點。當視窗大小改變時,結點會維持它們原來的相對位置。一個結點可以賦予多個位置,一個位置也可以賦予多個結點。
Figure 1-12是一個錨窗格,網格窗格在頂部,有兩個按鈕的
HBox窗格在底部偏右。
Figure 1-12 Sample Anchor Pane
Description of "Figure 1-12 Sample Anchor Pane" Example 1-8照上面建立了一個錨窗格。
Example 1-8 Create an Anchor Pane
AnchorPane anchorpane = new AnchorPane();
Button buttonSave = new Button("Save");
Button buttonCancel = new Button("Cancel");
HBox hbox = new HBox();
hbox.setPadding(new Insets(0, 10, 10, 10));
hbox.setSpacing(10);
hbox.getChildren().addAll(buttonSave, buttonCancel);
anchorpane.getChildren().addAll(grid,hbox); // Add grid from Example 1-5
AnchorPane.setBottomAnchor(hbox, 8.0);
AnchorPane.setRightAnchor(hbox, 5.0);
AnchorPane.setTopAnchor(grid, 10.0);
border.setCenter(anchorpane); // Add to BorderPane from Example 1-2
最後一行把錨窗格放在了邊框窗格中間,取代了先前的結點。結果見
Figure 1-13Figure 1-13 Anchor Pane in a Border Pane
Description of "Figure 1-13 Anchor Pane in a Border Pane"當視窗大小改變時,結點會維持它們原來的相對位置。
Figure 1-14在按鈕在底部,當視窗變低時,按鈕也向上移動了。
Figure 1-14 Resized Anchor Pane
Description of "Figure 1-14 Resized Anchor Pane"