Form(表單、表格)在視窗程式或是網頁中,都是很常見的顯示方式。以下就以「登入表單」來作為JavaFX Form的練習吧!



Hello JavaFX中,我們已經知道Stage和Scene的關係,也大概知道要如何製作出JavaFX的視窗程式。因此底下將會直接從Scene開始製作出我們想要的Form。

建立登入表單

​Layout(Pane)

Layout的概念,在Awt的時代就有了,可由藉由特殊的排版演算法來對畫面中的UI控制項進行較有彈性的排版。在JavaFX中,也提供了javafx.​scene.​layout APIs,經典的Border、Flow、Grid等排版方式也都還存在。只是到了JavaFX,Layout有個新的名稱──Pane。Layout也可以直接作為Scene的Root node。

要排出一個登入表單,Oracle提供的作法是用GridPane

GUI元件

要製作登入表單,我們需要將TextLabelTextFieldPasswordFieldButton加到GridPane內。但在這邊很奇怪的是,TextLabel差別在哪呢?以繼承關係來看,Text屬於shape底下的子類別,而Label屬於control底下的子類別,這表示Text並不算是控制項,而是需要被draw出來的「形狀」。在以往的AWT或是Swing中,沒有提供類似Text的套件,所以這在JavaFX中算是一個新概念:Layout中不再只能放置控制項,形狀也可以被放入Layout進行排版!

登入事件(Event)

在按下表單上的登入按鈕後,通常要執行一段驗證帳號密碼是否正確,然後判斷是否登入成功的程式。要如何在按鈕被按下後執行這段程式,就得靠EventHandler介面了,直接用Lambda語法來實作該介面即可。

撰寫程式

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class LoginJavaFX extends Application {

    @Override
    public void start(Stage primaryStage) {
        //Layout
        GridPane grid = new GridPane(); //Grid排版
        grid.setAlignment(Pos.CENTER); //Layout置中
        grid.setHgap(10); //水平距離
        grid.setVgap(10); //垂直距離

        grid.setPadding(new Insets(25, 25, 25, 25)); //填充邊界。Insets定義上、右、下、左四個方向的長度。

        //用Layout作為Scene的root node
        Scene scene = new Scene(grid, 300, 275);
        primaryStage.setScene(scene);

        //GUI元件
        Text scenetitle = new Text("歡迎");
        scenetitle.setFont(Font.font("Serif", FontWeight.NORMAL, 20));
        grid.add(scenetitle, 0, 0, 2, 1); //2,1是指這個元件要佔用2格的column和1格的row

        Label userName = new Label("帳號:");
        grid.add(userName, 0, 1);

        TextField userTextField = new TextField();
        grid.add(userTextField, 1, 1);

        Label pw = new Label("密碼:");
        grid.add(pw, 0, 2);

        PasswordField pwBox = new PasswordField();
        grid.add(pwBox, 1, 2);

        Button btn = new Button("登入");
        HBox hbBtn = new HBox(btn); //以新的HBox Layout來對Button進行排版,目的是為了讓Button在GridPane 1,4的位置中可以靠到最右邊。
        hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
        grid.add(hbBtn, 1, 4);

        //登入事件
        final Text actiontarget = new Text(); //顯示結果的Text
        grid.add(actiontarget, 1, 6);
        btn.setOnAction(e -> { //用lambda語法省略實作EventHandler介面
            actiontarget.setFill(Color.FIREBRICK);
            actiontarget.setText("登入成功!");
        });

        //顯示Stage
        primaryStage.setTitle("登入");
        primaryStage.show();
    }
}

執行結果: