天天看點

(翻譯)第二十九回 使用JavaFX2.0内置布局窗格

原文位址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-7

Figure 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-5

creates 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-9

Figure 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-11

Figure 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-13

Figure 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"