1. 程式人生 > >JavaFX入門(四):JavaFX佈局(一)

JavaFX入門(四):JavaFX佈局(一)

說道GUI程式設計一定要談到佈局,JavaFX內建了大量的佈局控制元件提供給我們使用。其實,JavaFX的佈局控制元件和介面元素控制元件都是繼承自javafx.scene.layout.Region類。我們這裡只看佈局控制元件類。佈局控制元件我們在介面上一般是看不到的,它一個容器用於放置其它可視的介面元素控制元件。(JavaFX線上API文件:JavaFX8 API Online
JavaFX佈局控制元件的類圖如下:
佈局類

下面簡單說說一些常用控制元件類的用法。這裡我們使用SceneBuilder進行介面的設計,SceneBuilder可以在Gluon下載。SceneBuilder的介面如下,我們可以簡單使用拖拽的方法進行介面設計。
SceneBuilder

1. Pane

Pane是其它佈局控制元件類的父類,我們可以將Pane看成一個絕對佈局控制元件,當我們將某個控制元件放置在Pane當中的時候,我們需要指定它的位置座標(layoutX和layoutY)。當我們將一個控制元件拖拽到Pane中的時候,會自動生成layoutX和layoutY座標。如圖是使用Pane為父容器設計的一個簡單介面:
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的時候,會有上下左右中的區域顯示。
BorderPane
我們在這5個區域放置5個標籤,如下圖:
BorderPane
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可以水平排列控制元件,不換行。如圖:
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類似的,垂直排列控制元件,不換列。如圖:
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中的控制元件會先水平排列,如果第一行滿了以後進入下一行繼續水平排列。垂直方向類似的,先垂直排列,如果第一列滿了以後進入第二列繼續垂直排列。如圖:
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為我們虛擬除了行和列的分割線:
GridPane
最後設計的介面如圖所示:
GridPane
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中我們可以很容易在右邊的屬性面板中設定錨定的方位和距離:
SceneBuilder
比如我們在左上角和右下角放置兩個Button,如圖:
AnchorPane
當我們調整窗體的大小的時候,錨定位置是不會變的。
AnchorPane
生成的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的大小,這樣就可以顯示出水平和垂直滾動條了。如下圖:
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瞭解對應類的一些屬性和方法。