布局(Pane)的作用将界面划分区域,用来放置其他可视的控件。JavaFx内置布局包括,FlowPane、TilePane、HBox、VBox、BorderPane、AnchorPane、GridPane、StackPane、DialogPane等。
FlowPane(流式布局)中的子元素被安置在流(flow)中,随着界面尺寸的变化自动改变布局。默认为横向流,可通过构造函数创建纵向流。具体创建过程:
public static FlowPane testFlowPane(){
//无参构造为默认(横向流),传入参数Orientation.VERTICAL为纵向流
//FlowPane res=new FlowPane(Orientation.VERTICAL);
FlowPane res=new FlowPane();
//设置内部元素边距(距离flowPane边框的距离)
res.setPadding(new Insets(20,20,20,20));
//设置横向间隔
res.setHgap(40);
//设置纵向间隔
res.setVgap(80);
Button bt1=new Button("button01");
Button bt2=new Button("button02");
Button bt3=new Button("button03");
Text text=new Text("I am a Text.");
Label l1=new Label("I am the first Label.");
Label l2=new Label("I am the second Label.");
res.getChildren().addAll(bt1,l1,text,l2,bt2,bt3);
return res;
}
FlowPane可设置参数,包括padding(初始元素到边界的距离),hgap(子元素的横向间距),vgap(子元素的纵向间距),prefWrapLength(FlowPane的初始长度/宽度,取决于流的方向:Orientation.VERTICAL为长度,默认为宽度),具体说明为:
执行代码:
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene=new Scene(PaneTest.testFlowPane());
primaryStage.setTitle("测试布局");
primaryStage.setScene(scene);
primaryStage.show();
}
TilePane是网格化的流布局,将每个子元素放在均匀分布的网格中。可设置的参数和FlowPane相同。prefColumns参数用于设置初始列数(列数会随着界面变化而变化),创建代码:
public static TilePane testTilePane(){
TilePane res=new TilePane(Orientation.HORIZONTAL);
//设置初始列数,随界面变化
res.setPrefColumns(4);
res.setPadding(new Insets(20,20,20,20));
res.setHgap(40);
res.setVgap(40);
//设置排列方式
res.setTileAlignment(Pos.CENTER);
addChildren(res);
return res;
}
具体参数说明:
结果演示:
HBox(HORIZONTAL)单行排列布局,VBox(VERTICAL)单列排列布局。可通过spacing参数设置子元素之间间隔。创建代码:
public static HBox testHBox(){
HBox res=new HBox();
res.setSpacing(10);
res.setPadding(new Insets(20,20,20,20));
addChildren(res);
return res;
}
public static VBox testVBox(){
//初始化设置间隔
VBox res=new VBox(10);
res.setPadding(new Insets(20,20,20,20));
addChildren(res);
return res;
}
效果展示:
BorderPane将界面划分为上、下、左、右、中五部分,如果某个部分包含子组件,则该区域将被其他部分占用。其中上、下两部分宽度和BorderPane的宽度相同,高度自适应子元素宽度;左、右两部分的宽度自适应子元素宽度,高度取决于上、下元素的高度;默认位置为:
各部分分布情况如下图:
可通过如下静态方法修改样式:
BorderPane.setAlignment(Node node,Pos.CENTER_RIGHT);
BorderPane创建代码如下:
public static BorderPane testBorder(){
BorderPane res=new BorderPane();
res.setPrefSize(600,400);
res.setPadding(new Insets(20,20,20,20));
Button topBtn = new Button("top button");
//设置子元素边界
BorderPane.setMargin(topBtn,new Insets(10,10,10,10));
//设置展示样式
BorderPane.setAlignment(topBtn,Pos.CENTER_RIGHT);
res.setTop(topBtn);
res.setBottom(new Button("bottom button"));
res.setLeft(new Button("left button"));
res.setRight(new Button("right button"));
res.setCenter(new Button("center button"));
return res;
}
默认效果展示:
AnchorPane(锚布局),和BorderPane类似,AnchorPane也将整个界面划分为上、下、左、右、中五个部分,但这五个部分只是逻辑划分,没有实际样式上的影响。可以设置AnchorPane内部的子元素距离上、下、左、右四边的距离,以将此元素固定在界面内。具体代码如下:
public static AnchorPane testAnchor(){
AnchorPane res=new AnchorPane();
res.setPrefSize(600,400);
res.setPadding(new Insets(10,10,10,10));
Button btn1=new Button("btn anchor top bottom left right");
//设定到锚定点距离
AnchorPane.setTopAnchor(btn1,10.0);
AnchorPane.setLeftAnchor(btn1,15.0);
AnchorPane.setRightAnchor(btn1,20.0);
AnchorPane.setBottomAnchor(btn1,25.0);
//只设定一个锚定方向
Button btn2=new Button("btn bottom");
AnchorPane.setBottomAnchor(btn2,5.0);
res.getChildren().addAll(btn1,btn2);
return res;
}
效果演示:
GridPane(网格布局),所有子元素被放置到内部的任何网格中,通过设置,子元素可以占用一个活多个网格,演示代码:
public static GridPane testGrid(){
GridPane res=new GridPane();
res.setPrefSize(400,300);
res.setHgap(20);
res.setVgap(20);
res.setPadding(new Insets(10,19,10,10));
Text text=new Text("I am a text, i span 3 col and 1 row.");
//设置元素起始列,起始行,所占列数,行数
res.add(text,0,0,3,2);
//设置显示样式
GridPane.setHalignment(text ,HPos.RIGHT);
Button bt1=new Button("button-1");
//设置元素所在列,所在行
res.add(bt1,0,2);
Button bt2=new Button("button-2");
res.add(bt2,1,2);
Button bt3=new Button("button-3");
res.add(bt3,2,2);
return res;
}
演示效果:
StackPane(栈布局)所有子元素沿z轴堆叠布局,每次只能看到栈顶的元素。为测试效果需要另外设置一个按钮用来控制栈顶元素切换。控制代码如下:
private static Button stackControl(StackPane pane){
Button bt=new Button("栈顶到栈底");
bt.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
ObservableList<Node> children = pane.getChildren();
if (children.size()>1){
//获取栈顶元素
Node node = children.get(children.size() - 1);
//控制栈顶元素到栈底
node.toBack();
}
}
});
return bt;
}
栈布局创建代码:
public static VBox testStack(){
StackPane pane=new StackPane();
Button bt1=new Button("first");
bt1.setStyle("-fx-font: bold italic 50px \"sans-serif\"");
pane.getChildren().add(bt1);
Text text=new Text("second");
text.setStyle("-fx-font: bold italic 50px \"sans-serif\"");
pane.getChildren().add(text);
Button bt2=new Button("third");
bt2.setStyle("-fx-font: bold italic 50px \"sans-serif\"");
pane.getChildren().add(bt2);
pane.setPrefSize(300,200);
pane.setPadding(new Insets(20,20,20,20));
pane.setAlignment(Pos.CENTER);
VBox res=new VBox();
res.getChildren().addAll(pane,stackControl(pane));
return res;
}
演示结果:
DialogPane(对话框布局)将整个区域氛围header(标题)、content(详情)、graphic(图形)、button(按钮)几个部分,常用语对话框中。可分别设置各部分的显示内容,具体代码实现如下:
public static DialogPane testDialog(){
DialogPane pane=new DialogPane();
//设置各区域显示内容
pane.setHeaderText("I am Headers");
pane.setContentText("I am a content text.");
Text text = new Text("Graphic");
text.setStyle("-fx-font: bold italic 50px 'sans-serif'");
pane.setGraphic(text);
pane.getButtonTypes().addAll(ButtonType.APPLY,ButtonType.OK,ButtonType.CLOSE);
pane.setPrefSize(300,200);
pane.setPadding(new Insets(20,20,20,20));
return pane;
}
显示效果如下:
以上为JavaFx中的主要内置布局功能介绍,在具体开发过程中可根据具体情况综和运用各种布局已实现功能。