JavaFX入門(四):JavaFX佈局(一)
說道GUI程式設計一定要談到佈局,JavaFX內建了大量的佈局控制元件提供給我們使用。其實,JavaFX的佈局控制元件和介面元素控制元件都是繼承自javafx.scene.layout.Region類。我們這裡只看佈局控制元件類。佈局控制元件我們在介面上一般是看不到的,它一個容器用於放置其它可視的介面元素控制元件。(JavaFX線上API文件:JavaFX8 API Online)
JavaFX佈局控制元件的類圖如下:
下面簡單說說一些常用控制元件類的用法。這裡我們使用SceneBuilder進行介面的設計,SceneBuilder可以在Gluon下載。SceneBuilder的介面如下,我們可以簡單使用拖拽的方法進行介面設計。
1. Pane
Pane是其它佈局控制元件類的父類,我們可以將Pane看成一個絕對佈局控制元件,當我們將某個控制元件放置在Pane當中的時候,我們需要指定它的位置座標(layoutX和layoutY)。當我們將一個控制元件拖拽到Pane中的時候,會自動生成layoutX和layoutY座標。如圖是使用Pane為父容器設計的一個簡單介面:
FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="350.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button layoutX="318.0" layoutY="210.0" mnemonicParsing="false" text="登入" />
<Label layoutX="136.0" layoutY="104.0" text="使用者名稱:" />
<Label layoutX="136.0" layoutY="162.0" text="密 碼:" />
<TextField layoutX="212.0" layoutY="100.0" />
<PasswordField layoutX="212.0" layoutY="158.0" />
</children>
</Pane>
2. BorderPane
BorderPane將介面分割上上下左右中5部分,我們可以將控制元件放置在其中。常見的一個用例場景就是,軟體主介面的上面是選單欄和工具條,左邊和右邊可能是文件或者內容列表或者常用的工具集合,然後中間是主要內容顯示區,下面是狀態列。
在SceneBuilder中我們將一個控制元件拖拽到BorderPane的時候,會有上下左右中的區域顯示。
我們在這5個區域放置5個標籤,如下圖:
FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<top>
<Label style="-fx-font-family: Arial; -fx-font-size: 20px;" text="上" BorderPane.alignment="CENTER" />
</top>
<left>
<Label style="-fx-font-family: Arial; -fx-font-size: 20px;" text="左" BorderPane.alignment="CENTER" />
</left>
<right>
<Label style="-fx-font-family: Arial; -fx-font-size: 20px;" text="右" BorderPane.alignment="CENTER" />
</right>
<center>
<Label style="-fx-font-family: Arial; -fx-font-size: 20px;" text="中" BorderPane.alignment="CENTER" />
</center>
<bottom>
<Label style="-fx-font-family: Arial; -fx-font-size: 20px;" text="下" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
該FXML程式碼中我們設定了字型,讓顯示更大一些。在後面我們將使用CSS樣式進行字型顏色等樣式的設定。
3. HBox
HBox可以水平排列控制元件,不換行。如圖:
FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="50.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button1" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button2" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button3" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button4" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button5" />
</children>
</HBox>
4. VBox
VBox類似的,垂直排列控制元件,不換列。如圖:
FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button1" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button2" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button3" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button4" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="100.0" text="Button5" />
</children>
</VBox>
5. FlowPane
FlowPane感覺像HBox和VBox的綜合體,FlowPane可以設定一個方向水平或者垂直。預設方向為水平,那麼放入FlowPane中的控制元件會先水平排列,如果第一行滿了以後進入下一行繼續水平排列。垂直方向類似的,先垂直排列,如果第一列滿了以後進入第二列繼續垂直排列。如圖:
可以看到水平方向上滿了以後,進入到下一行排列。
FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<FlowPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button mnemonicParsing="false" prefHeight="149.0" prefWidth="55.0" text="Button" />
<Button mnemonicParsing="false" text="Button" />
<Button mnemonicParsing="false" prefHeight="125.0" prefWidth="100.0" text="Button" />
<Button mnemonicParsing="false" prefHeight="71.0" prefWidth="55.0" text="Button" />
<Button mnemonicParsing="false" prefHeight="97.0" prefWidth="102.0" text="Button" />
<Button mnemonicParsing="false" prefHeight="112.0" prefWidth="213.0" text="Button" />
<Button mnemonicParsing="false" prefHeight="52.0" prefWidth="104.0" text="Button" />
</children>
</FlowPane>
6. GridPane
GridPane有點像HTML中的Table佈局,屬於比較靈活的佈局方式。預設情況下,控制元件均勻分佈在Grid或者說Table中。但是我們可以指定一個控制元件所佔的行列,讓其跨行和列分佈。當我們將一個元素拖拽到GridPane中的時候可以看到SceneBuilder為我們虛擬除了行和列的分割線:
最後設計的介面如圖所示:
FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="80.0" text="Button" />
<Button mnemonicParsing="false" prefHeight="180.0" prefWidth="55.0" text="Button" GridPane.columnIndex="1" GridPane.rowSpan="2" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="80.0" text="Button" GridPane.rowIndex="1" />
<Button mnemonicParsing="false" prefHeight="50.0" prefWidth="521.0" text="Button" GridPane.columnSpan="2" GridPane.rowIndex="2" />
</children>
</GridPane>
7. AnchorPane
AnchorPane可以設定一個控制元件的Anchor位置,感覺NET的GUI控制元件中最早提供這種控制元件的。比如說我們要將一個Button放置在左下角,離右邊100px,離下邊100px的位置,我們便可以使用AnchorPane控制元件。當視窗放大縮小的時候,該Button始終在左下角離右邊100px,離下邊100px的位置。通俗地說,AnchorPane可以將控制元件錨定到佈局面板的某個位置。
在SceneBuilder中我們可以很容易在右邊的屬性面板中設定錨定的方位和距離:
比如我們在左上角和右下角放置兩個Button,如圖:
當我們調整窗體的大小的時候,錨定位置是不會變的。
生成的FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button layoutX="174.0" layoutY="177.0" mnemonicParsing="false" text="右下" AnchorPane.bottomAnchor="100.0" AnchorPane.rightAnchor="100.0" />
<Button layoutX="106.0" layoutY="63.0" mnemonicParsing="false" text="左上" AnchorPane.leftAnchor="100.0" AnchorPane.topAnchor="100.0" />
</children>
</AnchorPane>
8. ScrollPane
ScrollPane顧名思義就是可以顯示滾動條的容器控制元件了。
我們在ScrollPane中放置一個TextArea文字域控制元件,並且設定TextArea的大小大於ScrollPane的大小,這樣就可以顯示出水平和垂直滾動條了。如下圖:
FXML程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.web.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<ScrollPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<content>
<TextArea prefHeight="600.0" prefWidth="500.0" />
</content>
</ScrollPane>
這一節我們說了一些常見的JavaFX佈局容器或者叫佈局控制元件,當然JavaFX還提供了很多其它的佈局控制元件。不過使用這一節常用的佈局就可以設計出常見的GUI介面了。
在我們用SceneBuilder設計介面的時候,自動生成的FXML檔案中的實體元素和屬性是和JavaFX中的類和屬性是對應的,我們可以通過FXML瞭解對應類的一些屬性和方法。