JavaFX开发桌面,移动端,嵌入式权威指南(三)——应用SceneBuilder开发用户界面

概述

JavaFX是用于构建富互联网应用程序的Java库。使用JavaFX开发的应用程序可以在各种设备上运行,如台式计算机,手机,物联网
设备,平板电脑等。上一章主要是介绍如何应用JavaFX使用编程声明方式开发用户界面。这一章主要应用SceneBuilder开发用户界面。

使用JavaFX SceneBuilder开发用户界面

这是安装好的SceneBuilder2.0,这是fxml文件编辑器,可以进行控件拖拽来搭建用户界面。
在这里插入图片描述

通过FXML设置舞台

将上一章中的 StageCoach程序改为fxml构建:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.Group?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.text.*?>
<Group fx:id="rootGroup"
       onMouseDragged="#mouseDraggedHandler"
       onMousePressed="#mousePressedHandler"
       xmlns="http://javafx.com/javafx/8"
       xmlns:fx="http://javafx.com/fxml/1"
       fx:controller="sample.StageCoachController">
    <children>
        <Rectangle fx:id="blue"
                   arcHeight="50.0"
                   arcWidth="50.0"
                   fill="SKYBLUE"
                   height="350.0"
                   strokeType="INSIDE"
                   width="250.0"/>
        <VBox fx:id="contentBox"
              layoutX="30.0"
              layoutY="20.0"
              spacing="10.0">
            <children>
                <Text fx:id="textStageX"
                      strokeType="OUTSIDE"
                      strokeWidth="0.0"
                      text="x:"
                      textOrigin="TOP"/>
                <Text fx:id="textStageY"
                      layoutX="10.0"
                      layoutY="23.0"
                      strokeType="OUTSIDE"
                      strokeWidth="0.0"
                      text="y:"
                      textOrigin="TOP"/>
                <Text fx:id="textStageH"
                      layoutX="10.0"
                      layoutY="50.0"
                      strokeType="OUTSIDE"
                      strokeWidth="0.0"
                      text="height:"
                      textOrigin="TOP"/>
                <Text fx:id="textStageW"
                      layoutX="10.0"
                      layoutY="77.0"
                      strokeType="OUTSIDE"
                      strokeWidth="0.0"
                      text="width:"
                      textOrigin="TOP"/>
                <Text fx:id="textStageF"
                      layoutX="10.0"
                      layoutY="104.0"
                      strokeType="OUTSIDE"
                      strokeWidth="0.0"
                      text="focused:"
                      textOrigin="TOP"/>
                <CheckBox fx:id="checkBoxResizable"
                          mnemonicParsing="false"
                          text="resizable"/>
                <CheckBox fx:id="checkBoxFullScreen"
                          mnemonicParsing="false"
                          text="fullScreen"/>
                <HBox fx:id="titleBox">
                    <children>
                        <Label fx:id="titleLabel"
                               text="title"/>
                        <TextField fx:id="titleTextField"
                                   text="Stage Coach"/>
                    </children>
                </HBox>
                <Button fx:id="toBackButton"
                        mnemonicParsing="false"
                        onAction="#toBackEventHandler"
                        text="toBack()"/>
                <Button fx:id="toFrontButton"
                        mnemonicParsing="false"
                        onAction="#toFrontEventHandler"
                        text="toFront()"/>
                <Button fx:id="closeButton"
                        mnemonicParsing="false"
                        onAction="#closeEventHandler"
                        text="close()"/>
            </children>
        </VBox>
    </children>
</Group>

在SceneBuilder中的显示效果:
在这里插入图片描述

理解fxml文件

  xmlns="http://javafx.com/javafx/8"
  xmlns:fx="http://javafx.com/fxml/1"

这两条命名空间将会被FXMLLoader使用。

   fx:controller="sample.StageCoachController"

它通知 JavaFX 运行时间,当前设计的 UI FXML 文件与其控制器Java 类协同工作。

因此,在加载FXML文件后,FXML文件中的顶层组节点可以在Java代码中作为舞台控制器类的根组字段访问和操作。在此FXML中
文件,我们分配了fx:id到我们创建的所有节点。当然如果不想程序化地操作节点,例如静态标签的情况,fx:id属性和控制器中的相应字段可以省略。

在程序中加载fxml

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.io.IOException;
import java.util.List;

public class StageCoachMainWithFxml extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) throws IOException {
        final StageStyle stageStyle = configStageStyle();
        FXMLLoader fxmlLoader = new FXMLLoader(StageCoachMainWithFxml.class
                .getResource("StageCoach.fxml"));
        Group rootGroup = fxmlLoader.load();
        final StageCoachController controller = fxmlLoader.getController();
        controller.setStage(stage);
        controller.setupBinding(stageStyle);
        Scene scene = new Scene(rootGroup, 250, 350);
        scene.setFill(Color.TRANSPARENT);
        stage.setScene(scene);
        stage.setOnCloseRequest(we -> System.out.println("Stage is closing"));
        stage.show();
        Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();
        stage.setX((primScreenBounds.getWidth() - stage.getWidth()) / 2);
        stage.setY((primScreenBounds.getHeight() - stage.getHeight()) / 4);
    }

    private StageStyle configStageStyle() {
        StageStyle stageStyle = StageStyle.DECORATED;
        List<String> unnamedParams = getParameters().getUnnamed();
        if (unnamedParams.size() > 0) {
            String stageStyleParam = unnamedParams.get(0);
            if (stageStyleParam.equalsIgnoreCase("transparent")) {
                stageStyle = StageStyle.TRANSPARENT;
            } else if (stageStyleParam.equalsIgnoreCase("undecorated")) {
                stageStyle = StageStyle.UNDECORATED;
            } else if (stageStyleParam.equalsIgnoreCase("utility")) {
                stageStyle = StageStyle.UTILITY;
            }
        }
        return stageStyle;
    }
}

理解控制类

package sample;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

/**
 * @author: Administrator
 * @date: 2021/03/18 12:52
 * @description:
 */
public class StageCoachController {
    @FXML
    private Rectangle blue;
    @FXML
    private VBox contentBox;
    @FXML
    private Text textStageX;
    @FXML
    private Text textStageY;
    @FXML
    private Text textStageH;
    @FXML
    private Text textStageW;
    @FXML
    private Text textStageF;
    @FXML
    private CheckBox checkBoxResizable;
    @FXML
    private CheckBox checkBoxFullScreen;
    @FXML
    private HBox titleBox;
    @FXML
    private Label titleLabel;
    @FXML
    private TextField titleTextField;
    @FXML
    private Button toBackButton;
    @FXML
    private Button toFrontButton;
    @FXML
    private Button closeButton;
    private Stage stage;
    private StringProperty title = new SimpleStringProperty();
    private double dragAnchorX;
    private double dragAnchorY;
    public void setStage(Stage stage) {
        this.stage = stage;
    }
    public void setupBinding(StageStyle stageStyle) {
        checkBoxResizable.setDisable(stageStyle == StageStyle.TRANSPARENT
                || stageStyle == StageStyle.UNDECORATED);
        textStageX.textProperty().bind(new SimpleStringProperty("x: ")
                .concat(stage.xProperty().asString()));
        textStageY.textProperty().bind(new SimpleStringProperty("y: ")
                .concat(stage.yProperty().asString()));
        textStageW.textProperty().bind(new SimpleStringProperty("width: ")
                .concat(stage.widthProperty().asString()));
        textStageH.textProperty().bind(new SimpleStringProperty("height: ")
                .concat(stage.heightProperty().asString()));
        textStageF.textProperty().bind(new SimpleStringProperty("focused: ")
                .concat(stage.focusedProperty().asString()));
        stage.setResizable(true);
        checkBoxResizable.selectedProperty()
                .bindBidirectional(stage.resizableProperty());
        checkBoxFullScreen.selectedProperty().addListener((ov, oldValue, newValue) ->
                stage.setFullScreen(checkBoxFullScreen.selectedProperty().getValue()));
        title.bind(titleTextField.textProperty());
        stage.titleProperty().bind(title);
        stage.initStyle(stageStyle);
    }
    @FXML
    public void toBackEventHandler(ActionEvent e) {
        stage.toBack();
    }
    @FXML
    public void toFrontEventHandler(ActionEvent e) {
        stage.toFront();
    }
    @FXML
    public void closeEventHandler(ActionEvent e) {
        stage.close();
    }
    @FXML
    public void mousePressedHandler(MouseEvent me) {
        dragAnchorX = me.getScreenX() - stage.getX();
        dragAnchorY = me.getScreenY() - stage.getY();
    }
    @FXML
    public void mouseDraggedHandler(MouseEvent me) {
        stage.setX(me.getScreenX() - dragAnchorX);
        stage.setY(me.getScreenY() - dragAnchorY);
    }
}

唯一需要一些解释的是@FXML注释。它属于javafx.fxml包。这是一个标记注释,具有可应用于字段和方法的运行时保留。当应用于字段时,@FXML注释告诉 JavaFX 程序,该字段的名称使用FXML文件中的元素 fx:id 的值。当应用于一种方法时,@FXML注释告诉JavaFX程序该方法的名称可以用作事件处理器属性的值。字段和方法使用@FXML注解修饰,使得程序可以操作FXML中的组件。 可以对修饰的字段进行参数的绑定,绑定事件处理器。对修饰的方法可以将行为绑定到相应fxml中的组件。例如fxml文件中button设置了onAction="#toFrontEventHandler" 属性,可以在控制器中使用如下方法绑定到相应的button.

@FXML
    public void toFrontEventHandler(ActionEvent e) {
        stage.toFront();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NewTech精选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值