Windows Java JavaFX Idea 开发环境搭建

news2024/12/26 13:29:12

博文目录

文章目录

  • JavaFX 简单说明
    • JavaFX 版本说明
    • JavaFX 与 JDK 的关系
    • JavaFX 与 JDK Modular (JDK 9 模块化系统)
    • JavaFX 模块说明 (JavaFX 20)
    • JavaFX Scene Builder
    • 构建 JavaFX 应用程序的两种选择
  • 环境搭建 `建议先阅读下方引用的官方文档, 与本章节做相互印证与理解`
    • 版本选择
    • JavaFX SDK (使用 Maven 等构建工具的无需下载 JavaFX SDK)
    • IntelliJ Idea 安装配置
    • IntelliJ Idea `Java Project` 开发方式
      • 新建工程
      • 添加 JavaFX SDK 依赖
      • 关联 JavaFX SDK 源码
      • 创建第一个 JavaFX 窗体
        • HelloWorld.java
        • 错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序
        • 效果展示
    • IntelliJ Idea `JavaFX Project` 开发方式 (Maven)
      • 新建工程
      • 自带初始模板代码如下
        • pom.xml
        • module-info.java
        • HelloApplication.java
        • hello-view.fxml
        • HelloController.java
      • 运行 HelloApplication
  • Scene Builder 19.0.0 安装与配置
  • JavaFX 开发需要掌握的知识点
    • Java 模块化技术基础
    • JavaFX 基础编程模型
    • JavaFX MVC 架构
    • JavafX 事件处理机制
    • JavaFX 多窗体编程与数据传输
    • JavaFX 数据绑定机制
    • Java MVVM
    • JavaFX 多线程
    • JavaFX 集成第三方框架, 如 RxJava
    • JavaFX Chart 图表
  • 打包与分发
    • 添加一个标准的
    • 非模块化工程


JavaFX 简单说明

JavaFX 官网

JavaFX 是一个开源的下一代客户端应用程序平台,适用于基于 Java 构建的桌面、移动和嵌入式系统。它是许多个人和公司的协作成果,目标是为开发富客户端应用程序生成一个现代、高效且功能齐全的工具包。

JavaFX 主要致力于富客户端开发,以弥补 swing 的缺陷,主要提供图形库与 media 库,支持 audio,video,graphics,animation,3D 等,同时采用现代化的 css 方式支持界面设计。同时又采用 XUI 方式以 XML 方式设计 UI 界面,达到显示与逻辑的分离。与 android 这方面确实有点相似性。

Java 8 新特性探究(十三)JavaFX 8 新特性以及开发 2048 游戏

跟 java 在服务器端和 web 端成绩相比,桌面一直是 java 的软肋,于是 Sun 公司在 2008 年推出 JavaFX,弥补桌面软件的缺陷,请看下图 JavaFX 一路走过来的改进
在这里插入图片描述
从上图看出,一开始推出时候,开发者需使用一种名为 JavaFX Script 的静态的、声明式的编程语言来开发 JavaFX 应用程序。因为 JavaFX Script 将会被编译为 Java bytecode,程序员可以使用 Java 代码代替。 JavaFX 2.0 之后的版本摒弃了 JavaFX Script 语言,而作为一个 Java API 来使用。因此使用 JavaFX 平台实现的应用程序将直接通过标准 Java 代码来实现。 JavaFX 2.0 包含非常丰富的 UI 控件、图形和多媒体特性用于简化可视化应用的开发,WebView 可直接在应用中嵌入网页;另外 2.0 版本允许使用 FXML 进行 UI 定义,这是一个脚本化基于 XML 的标识语言。

从 JDK 7u6 开始,JavaFX 就与 JDK 捆绑在一起了,JavaFX 团队称,下一个版本将是 8.0,目前所有的工作都已经围绕 8.0 库进行。这是因为 JavaFX 将捆绑在 Java 8 中,因此该团队决定跳过几个版本号,迎头赶上 Java 8。

目前我还不知道 Java 平台其他的更好的客户端库

JavaFX 版本说明

官网 版本说明

在这里插入图片描述

截止到 20230423, JavaFX 的版本如上图所示. 有几个点需要注意

  • JavaFX 11 和 17 是长期支持版本, 会有专人做更新和修复工作, 除此之外的版本都是非长期支持版本
  • JavaFX 11 虽然是长期支持版本, 但是其将在 202309 到期, 而且有更好的 17 可选, 所以 11 不推荐使用
  • JavaFX 20 是当前的最新发布版本, 但不是长期支持版本. 最新发布版本会有最多最全的新特性, 有需要可以使用该版本
  • JavaFX 21 是早期访问版本, 相当于测试版本, 一般不建议使用, 看中某些新特性尝鲜可以试试
  • 灰色的 JavaFX 12 / 13 / 14 / 15 / 16 / 18 已经不再更新, 不建议使用. 19 虽然还在更新, 但是估计用不了多久也会停止, 同样不建议使用

综上所述, 比较推荐 JavaFX 17 / 20, 17 有长期支持, 20 有最新最全的特性

JavaFX 与 JDK 的关系

JavaFX 建立在 JDK 之上,是一个独立的组件。

从 JDK 11 开始, JavaFX 与 JDK 分开发布, JavaFX 不再集成于 JDK 中

JavaFXJDK
2017 or later
1911 or later
1811 or later
1711 or later
1611 or later
1511 or later
1411 or later
1311 or later
1211 or later
11OpenJDK 10 / JDK 11 or later
8集成于 JDK 8

JavaFX 与 JDK Modular (JDK 9 模块化系统)

在 Java 8 之后,JavaFX 从 JDK 中分离出来,然后在 Java 9 时,Java 引入了 Java 模块化系统。从那之后,JavaFX 要求使用 Java 模块化系统来运行 JavaFX。因此,当直接使用 Java 8 以上的环境运行非模块化的 JavaFX 项目时就会出现如下报错。

错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序

解决方法见下文 错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序 部分

JavaFX 模块说明 (JavaFX 20)

官网 JavaFX 20 API 文档

  • javafx.base: 定义 JavaFX UI 工具包的基本 API,包括绑定、属性、集合和事件的 API。
  • javafx.controls: 定义可用于 JavaFX UI 工具包的 UI 控件、图表和外观。
  • javafx.fxml: 为 JavaFX UI 工具包定义 FXML API。
  • javafx.graphics: 为 JavaFX UI 工具包定义核心场景图 API(例如布局容器、应用程序生命周期、形状、转换、画布、输入、绘画、图像处理和效果),以​​及动画、CSS、并发、几何、打印的 API , 和开窗。
  • javafx.media: 定义用于播放媒体和音频内容的 API,作为 JavaFX UI 工具包的一部分,包括MediaView和 MediaPlayer.
  • javafx.swing: 为 JavaFX UI 工具包中包含的 JavaFX/Swing 互操作支持定义 API,包括SwingNode(用于将 Swing 嵌入 JavaFX 应用程序)和 JFXPanel(用于将 JavaFX 嵌入 Swing 应用程序)。
  • javafx.web: 为 JavaFX UI 工具包中包含的 WebView 功能定义 API。

JavaFX Scene Builder

官网 Scene Builder 下载

Scene Builder 是针对 JavaFX FXML UI 的拖拽式页面设计编码工具, 免费且开源

当前版本是 Scene Builder 19.0.0, 运行需要 JDK 11 or later

如果使用 JDK 8 的 JavaFX, 可以下载 Scene Builder 8.5.0

构建 JavaFX 应用程序的两种选择

  • JavaFX SDK, 原生 Java SE 工程开发 JavaFX 应用程序, 需要下载并引入 JavaFX SDK 提供的依赖 jar, 在 lib 目录下
  • Maven / Gradle 等构建工具, 使用构建工具可以从中央仓库下载指定版本的 JavaFX 相关依赖, 和使用 JavaFX SDK 本质是一样的

建议选择使用 Maven 等构建工具

环境搭建 建议先阅读下方引用的官方文档, 与本章节做相互印证与理解

官网 JavaFX 和 IntelliJ IDEA

版本选择

在这里插入图片描述

本次学习使用最新版 JavaFX 20, 所以需要使用 JDK 17

JavaFX SDK (使用 Maven 等构建工具的无需下载 JavaFX SDK)

官网 JavaFX SDK 下载

  • 先选择合适的 SDK 版本, 建议从 11 / 17 / 20 / Early Access 这 4 个版本中选择
  • 然后下载并解压该 SDK, 如 C:\mrathena\develop\javafx-sdk-20.0.1在这里插入图片描述

IntelliJ Idea 安装配置

IntelliJ Idea Java Project 开发方式

以这种方式创建的工程默认是非模块化工程, 如果需要改成模块化工程, 需自行添加并编写 module-info.java

module-info.java 与包结构的起始路径在同一个目录下

新建工程

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
初始工程结构如下
在这里插入图片描述

添加 JavaFX SDK 依赖

打开工程结构设置

在这里插入图片描述

确保当前使用的是 JDK 17

在这里插入图片描述
在这里插入图片描述

在 Libraries 里添加 JavaFX SDK 的 lib 目录, 其下所有 jar 文件都会被自动依赖到工程中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

关联 JavaFX SDK 源码

随便打开一个 JavaFX 的 class 文件, 如 javafx.application.Application, Idea 上方会提示 Choose sources ... 即可选择合适的源码关联, JavaFX SDK 的源码就是文件夹下的 src.zip

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建第一个 JavaFX 窗体

HelloWorld.java

package com.mrathena;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloWorld extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        String javaVersion = System.getProperty("java.version");
        String javafxVersion = System.getProperty("javafx.version");
        Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
        Scene scene = new Scene(new StackPane(l), 640, 480);
        stage.setScene(scene);
        stage.show();
    }

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

错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序

当使用 Java 8 以上的环境运行非模块化的 JavaFX 项目时就会出现如下报错

错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序

解决方法也有多种

  • 使用 JDK 8, 不建议, 不能从根源解决问题

  • 改造本工程为模块化工程, 推荐使用该方法. 添加 module-info.java 模块申明文件, 内容如下

    module com.mrathena { // 定义模块名称, 通常和包名一致
        requires javafx.controls; // 引入 javafx.controls 模块
        exports com.mrathena; // 暴露本模块中的指定包(不包含子包) // Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class com.mrathena.HelloWorld (in module com.mrathena) because module com.mrathena does not export com.mrathena to module javafx.graphics
    }
    
  • 在运行配置里添加 vm 参数 --module-path 下载的JavaFx的SDK的lib文件夹的完整路径 --add-modules javafx.controls,javafx.fxml, 如果路径里有空格, 则路径要加上双引号 ""
    在这里插入图片描述
    为了方便, 可以给 JavaFX 运行模板配置该 vm 参数, 后续运行其他主类也会自动加上该参数在这里插入图片描述

  • 使用引导类, 在另一个类的 main 方法中调用主类的 main 方法, 会自动生成一个匿名的模块系统, 桌面程序可以运行, 但有警告提示

    4月 23, 2023 10:19:53 下午 com.sun.javafx.application.PlatformImpl startup
    警告: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @491dbe27'
    

效果展示

在这里插入图片描述

IntelliJ Idea JavaFX Project 开发方式 (Maven)

如果使用 Maven 开发 JavaFX 应用程序,则不必下载 JavaFX SDK。只需在 pom.xml 中指定想要的模块和版本,构建系统就会下载所需的模块,包括所属平台的本机库。本机库就是不同系统下的具体实现, 如下图中带 win 的依赖

在这里插入图片描述

  • D:\resource\develop\maven\repository\org\openjfx\javafx-controls\20.0.1\javafx-controls-20.0.1.jar
  • D:\resource\develop\maven\repository\org\openjfx\javafx-controls\20.0.1\javafx-controls-20.0.1-win.jar

新建工程

通过 Idea JavaFX Project 创建的就是 Maven 工程, 或者也可以创建 JavaFX Archetype 的 Maven 工程(需要自行导入该骨架), 不如 Idea JavaFX Project 来的方便

在这里插入图片描述
在这里插入图片描述

不知道这些依赖是干什么的先不选, 初始工程结构如下

在这里插入图片描述

默认就是 模块化结构的工程, pom.xml 中 javafx 的依赖版本默认是 17.0.0.1, 改成 20.0.1 即可

自带初始模板代码如下

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mrathena</groupId>
    <artifactId>javafx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>java.javafx.starter</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>20.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>20.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.9.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.7</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>com.mrathena.javafx/com.mrathena.javafx.HelloApplication</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

module-info.java

module com.mrathena.javafx {
    requires javafx.controls;
    requires javafx.fxml;

    opens com.mrathena.javafx to javafx.fxml;
    exports com.mrathena.javafx;
}

HelloApplication.java

package com.mrathena.javafx;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 320, 240);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }

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

hello-view.fxml

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
      fx:controller="com.mrathena.javafx.HelloController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
    </padding>

    <Label fx:id="welcomeText"/>
    <Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>

HelloController.java

package com.mrathena.javafx;

import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class HelloController {
    @FXML
    private Label welcomeText;

    @FXML
    protected void onHelloButtonClick() {
        welcomeText.setText("Welcome to JavaFX Application!");
    }
}

运行 HelloApplication

在这里插入图片描述

Scene Builder 19.0.0 安装与配置

官网 Scene Builder 下载

下载好 SceneBuilder-19.0.0.msi 并运行, 选择合适的安装位置, 安装即可

在 Idea 里右键某个 fxml 文件, 选择使用 SceneBuilder 打开, 即可设置与 SceneBuilder.exe 的关联, 设置过后, 后续即可直接用 SceneBuilder 打开 fxml 文件, 编辑好后 Ctrl+S 保存即可直接作用于 fxml 文件

在这里插入图片描述
在这里插入图片描述

JavaFX 开发需要掌握的知识点

Java 模块化技术基础

51-Java模块化技术基础

  • module-info.java
  • –module-path
  • –add-modules
  • jmods
  • jlink

JavaFX 基础编程模型

54-把握JavaFX编程模型

  • JavaFX 应用程序的主类需要继承自 javafx.application.Application 类, 然后重写其 start 方法, 此方法是所有 JavaFX 应用程序的入口点
  • JavaFX 应用程序将 UI 容器定义为 舞台(Stage)场景(Scene), Stage 是顶级容器, 它对应于窗体, 其内容有 Scene 决定. Scene 是所有可视化内容的 容器(Container). JavaFX 应用程序的可视化界面通常由 控件(Control)形状(Shape) 构成, 放到 Scene 中
  • JavaFX 中, Scene 中的内容会以由 图形节点(Node) 构成的分层 场景图(Scene Graph) 来展现. SceneGraph 其实就是一颗多叉树, 各种控件都是树中的节点, 最底层的节点通常是诸如按钮之类的控件, 也可以是 Circle 之类的图形. 拥有子树的节点称为容器, 在 JavaFX 中称为 布局(Layout)
  • Stage 与 Scene 是 1:1 的关系, Scene 与场景图的根节点是 1:1 的关系
  • JavaFX 应用程序的生命周期: init - start - running - stop, init / start / stop 由抽象类 javafx.application.Application 定义, 可以自定义覆盖
  • Stage 的生命周期: close / hide / show 等等, 可以给 Stage 挂接相关事件

JavaFX MVC 架构

55-JavaFX应用的MVC架构

  • MainClass: 程序的入口点, 通常包容管理多窗体, 实现各控制器之间相互通讯的相关代码
  • Model: 就是封装了数据的 JavaBean
  • View: 使用 FXML 编写, 包容可视化的 UI 控件, 使用户使用程序的媒介, 关联着一个控制器
  • Controller: 包容程序的应用逻辑, 负责响应用户操作, 负责在 View 和 Model 之间实现数据同步

JavafX 事件处理机制

56-把握JavaFX事件处理机制原理

  • 桌面应用都是 事件驱动 的, 事件(Event) 表示程序所感兴趣的某件事情发生了, 比如鼠标移动事件, 按键按下事件等
  • JavaFX 中, 事件是 javafx.event.Event 类或其任何子类的实例, JavaFX 提供了多种事件, 比如 DragEvent(拖动事件), KeyEvent, MouseEvent 等, JavaFX 提供的内置 UI 控件和图形对象, 都可以触发特定事件
  • JavaFX 中可以通过 Java 代码绑定事件, 也可以通过 FXML 绑定事件, 通过 FXML 声明的事件的方法要加 @FXML 注解
  • 事件派发链: 事件在控件树中的传播过程. 事件派发链是一个双向链表, 有时间目标对象负责创建, 事件发生时, 事件对象会在链中传播. 事件响应方法分为 EventFilter 和 EventHandler 两类, 先执行 EventFilter 事件链
    • EventFilter: 下沉: 从根节点向下来到事件发生节点
    • EventHandler: 冒泡: 从事件发生节点向上去往根节点
    • 举例: HBox 里放了个 Label: 两者都分别挂载了两个方向的 MOUSE_PRESSED 事件, 如果在标签上点击左键, 则会按照先 EventFilter 再 EventHandler 的顺序来调用响应方法, Filter 的先执行 hBox 的再执行 label 的, Handler 的先执行 label 的再执行 hBox 的
      • hBox.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {})
      • hBox.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> {})
      • label.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {})
      • label.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> {})

JavaFX 多窗体编程与数据传输

57-JavaFX多窗体编程

  • 每个 Stage 对应一个窗体
  • 模态窗体: 具有父子关系且子窗体出现时, 父窗体不能操作
  • 对象互相传递消息: 就是对象互相持有引用, 调用对方的方法来传递数据, 在 JavaFX 中窗体间传递信息靠的就是各 Controller 相互引用, 调用回调函数

JavaFX 数据绑定机制

58-JavaFX数据绑定机制及应用

  • JavaFX Bean Property: 提供了很多 SimpleIntegerProperty 之类的工具类, 可以绑定值改变事件, 代码操作值, 绑定的 UI 自动跟新
  • JavaFX 数据绑定编程模式
    • 绑定数据源: 具备改变通知能力的数据对象与数据集合, 包括 JavaFX Bean Property / ObservableValue / ObservableList<T>
    • JavaFX 应用程序的 UI 界面: 包容 TableView / Label 等支持数据绑定的控件
    • JavaFX 数据绑定机制: Binding 对象
    • 举例: Circle 始终居于窗体中央, Circle 自带圆心横纵坐标的 Property 属性, Scene 自带宽度高度的 Property 属性
      • circle.centerXProperty().bind(Bindings.divide(scene.widthProperty(), 2));
      • circle.centerYProperty().bind(Bindings.divide(scene.heightProperty(), 2));
  • 优点: 业务逻辑与 UI 分离, 绑定好关系之后, 属性值变化, UI 会自动更新, 无需代码修改 UI
  • 双向绑定:
    • 举例: 两个 TextField 保持内容一致, 再任何一方修改, 另一方保持内容相同
      • repeater.textProperty().bindBidirectional(speaker.textProperty());

Java MVVM

59-JavaFX实现MVVM架构

  • View: 还是 FXML 定义的 UI
  • ViewModel: 和 MVC 中的 Model 一样, 但是使用 JavaFX Bean Property / ObservableValue / ObservableList<T> 具备值变化通知能力的工具来做成员属性, 其与 UI 上的某些控件的值相对应
  • Controller: 实现 javafx.fxml.Initializable 接口, 在其提供的 initialize 方法中做如下事情
    • 控件的事件挂载
    • ViewModel 和 UI 控件做双向数据绑定, 这样 Controller 直接操作 ViewModel 的属性即可同步到 UI, 在 UI 相关控件上修改值也能同步到 ViewModel 的相关字段中
    • 注意: UI 变化完全由数据绑定后自行更新, Controller 不做任何 UI 的控制
  • 举例: 登录功能, UI 有 username 和 password 两个 TextField, login 和 cancel 两个 Button
    • LoginApplication: 程序主类入口
    • LoginViewModel: 持有 usernameProperty 和 passwordProperty 两个 StringProperty, 还有相关的 getter / setter / protertyGetter
    • LoginController: 实现 login 和 cancel 两个方法, 在 initialize 方法中做 login 按钮和 login 方法的绑定, cancel 按钮和 cancel 方法的绑定, ViewModel 中 usernameProperty 和 username 文本框的双向绑定, ViewModel 中 passwordProperty 和 password 文本框的双向绑定
      • login: 通过获取并验证 ViewModel 中 usernameProperty 和 passwordProperty 的值做合适的逻辑处理
      • cancel: 清空 ViewModel 中 usernameProperty 和 passwordProperty 的值
  • 也可以把 login 中的业务逻辑放到其他方法或类中, 这样 单元测试 时可以只测业务不看 UI

JavaFX 多线程

60-JavaFX多线程及典型示例展示

  • UI 操作有专门的 JavaFX Application Thread 线程负责, 自行创建的线程不允许操作 UI
  • 主线程中不要直接调用耗时很久的方法, 会导致窗体冻结. 要用一个线程去这些任务, 如果任务完成后需要更新 UI, 则可以使用 Platform.runLater(() - > {}) 的方式, 这里 Lambda 表达式执行的操作会被推送到 JavaFX Application Thread 线程中执行, 所以可以访问 UI 控件
  • JavaFX 的 Worker 和 Task: 提供了后台线程运行并更新 UI 的相关功能封装, 支持中途取消

JavaFX 集成第三方框架, 如 RxJava

  • RxJava: 一款响应式的框架
  • 需要注意一点, 需要更新 UI 的地方用 Platform.runLater

JavaFX Chart 图表

  • JavaFX 内置了 图表 相关控件, 支持数据绑定, 可做一些数据可视化相关功能

打包与分发

  • Fat Jar: 运行时不再需要 -classpath 参数, 将依赖 Jar 中的相关类抽取到目标 Jar 包中

添加一个标准的

非模块化工程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/455909.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue 3组件传值 、组件通信

本文采用<script setup />的写法&#xff0c;比options API更自由。那么我们就来说说以下七种组件通信方式&#xff1a; props emit v-model refs provide/inject eventBus vuex/pinia 举个例子 本文将使用下面的演示&#xff0c;如下图所示&#xff1a; 上图中…

【社区图书馆】《新程序员005:开源深度指南 新金融背后的科技力量》

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰来给大家推荐一本书&#xff0c;此书的书名为新程序员005&#xff1a;开源深度指南 & 新金融背后的科技力量&#xff0c;为什么小雅兰今天要给大家推荐这样一本书呢&#xff1f;好啦&#xff0c;现在&#xff0c;…

[python][pcl]python-pcl案例之兔子显示

兔子pcd文件下载&#xff1a;firc.lanzoux.com/iLfSgg749ab# -*- coding: utf-8 -*- # Point cloud library import pcl import pcl.pcl_visualization# Opencv # import opencv import cv2def main():# These are track bar initial settings adjusted to the given pointclou…

牛客网Verilog刷题——VL12

牛客网Verilog刷题——VL12 题目答案 题目 4bit超前进位加法器的逻辑表达式如下&#xff1a; G i G_i Gi​ A i A_i Ai​ B i B_i Bi​&#xff0c; P i P_i Pi​ A i A_i Ai​ ⊕ \oplus ⊕ B i B_i Bi​   和&#xff1a; S i S_i Si​ P i P_i Pi​ ⊕ \oplus ⊕ C i − 1…

DHCP协议详解

DHCP是什么 1.1 DHCP定义 DHCP&#xff08; Dynamic Host Configuration Protocol&#xff0c; 动态主机配置协议&#xff09;定义&#xff1a; 存在于应用层&#xff08;OSI&#xff09; 前身是BOOTP&#xff08;Bootstrap Protocol&#xff09;协议 是一个使用UDP&#xff08…

如何正确选择集体渲染(云渲染)和gpu离线渲染

在数字娱乐领域&#xff0c;渲染是制作高质量影像的关键步骤之一。随着技术的不断发展和应用的广泛普及&#xff0c;渲染方式也在不断演进。目前&#xff0c;集体渲染&#xff08;云渲染&#xff09;和GPU离线渲染是两种比较流行的渲染方式。那么&#xff0c;哪种方式会更快呢&…

一文了解什么是5G

5G是第五代移动网络。它是继1G、2G、3G、4G网络之后的新的全球无线标准。5G 支持一种新型网络&#xff0c;旨在将几乎所有人和所有事物连接在一起&#xff0c;包括机器、物体和设备。 一、前几代移动网络和5G有什么区别 第一代 – 1G 1980 年代&#xff1a;1G 传送模拟语音。…

软件测试标准升级|新版25000标准解读

广电计量 目录 收起 一、覆盖软件产品八大特性的测试依据及准则 二、信息安全测试的关键要点 三、兼容性测试的关键要点 四、功能测试的关键要点 五、性能效率测试的关键要点 六、易用性测试的关键要点 七、可靠性测试的关键要点 八、维护性测试的关键要点 九、可移植…

Linux各文件权限

参考:https://blog.csdn.net/weixin_45423515/article/details/126652740 一、切换root权限 既然root是最大的权限&#xff0c;那么这里就来了解一下如果切换到root用户。 su - //切换成root 这就是切换人的权限&#xff0c;但是大多数情况是root权限不会轻易的分给普通用户…

NIS服务

NIS 文章目录 NIS一、NIS二、简介2.1 NIS的产生2.2 什么是NIS&#xff1f; 三、NIS的相关组件3.1 服务端3.1.1 配置文件3.1.2 主要服务3.1.3 数据库相关指令 3.2 客户端3.2.1 配置文件3.2.2 主要指令 四、NIS环境4.1 NIS所需的软件包4.2 NIS Server (Master/Slave)4.3 NIS Clie…

unity3d---物体加点击事件

目录 1.给需要点击点物体加collider 2.层级面板加EventSystem 3. 相机加Physics Raycaster 4.物体单独响应点击事件 5.控制脚本实现各物体的点击事件 6.点击ui时屏蔽 物体点击事件 1.给需要点击点物体加collider 2.层级面板加EventSystem 3. 相机加Physics Raycaster 2d…

机器学习 Rider数据集分析和预测

介绍数据集 ride_id&#xff1a;乘车ID rideable_type&#xff1a;乘车类型 started_at&#xff1a;开始日期 ended_at &#xff1a;结束日期 start_station_name&#xff1a;开始站的名字 start_station_id&#xff1a;开始站的ID end_station_name&#xff1a;结束站的名字 …

魔百和UNT403G 国科芯片2+8 安卓9.0 免拆机纯净线刷包

固件特点&#xff1a; 1、本固件在UNT403G 盒子上测试可用&#xff0c; 其它盒子请慎 重使用&#xff1b; 2、支持原装遥控器&#xff0c;语音蓝牙遥控器&#xff1b; 3、固件压缩包有刷机教程&#xff0c;请一定仔细阅读。 4、刷机后三网通用&#xff0c;可自由安装应用&#…

NewBing 边栏快捷插件没有了!如何解决?如何脱离浏览器使用 New Bing?

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;蚂蚁集团高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《EffectiveJava》独家解析》专栏作者。 热门文章推荐…

【移动端网页布局】流式布局 ① ( 流式布局简介 | 百分比布局 / 非固定像素布局 | 根据屏幕尺寸 / 设备类型自动调整网页布局 )

文章目录 一、流式布局简介二、流式布局代码示例 一、流式布局简介 流式布局 又称为 百分比布局 / 非固定像素布局 ; 为 流式布局 中 盒子模型 设置 百分比宽度 , 其大小可以根据屏幕宽度自适应伸缩 , 该盒子没有像素限制 , 内容自动向左右两边填充 ; 流式布局 可以 根据 设备…

蓝库云|究竟什么是ERP?它对企业有什么重要性作用呢

一、什么是ERP ERP全称为Enterprise Resource Planning&#xff0c;即企业资源计划&#xff0c;是一种运用信息技术手段来集成管理企业内部所有资源&#xff0c;协调各项业务、机构、流程和人员&#xff0c;实现高效、协同、合规经营的商业管理软件。ERP系统包括销售、采购、物…

Docker-compose组成|搭建(nginx|tomcat)

Docker-compose组成|搭建&#xff08;nginx|tomcat&#xff09; 一 Docker-Compose二 Docker-Compose安装部署三 YML文件编写注意事项四 docker Compose撰写nginx 镜像五 docker Compose撰写tomcat镜像 一 Docker-Compose 1、Docker-Compose使用场景 我们知道使用一个Dockerfi…

c/c++:栈帧,传值,传址,实参传值给形参,传地址指针给形参

c/c&#xff1a;栈帧&#xff0c;传值&#xff0c;传址&#xff0c;实参传值给形参&#xff0c;传地址指针给形参 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;此时学会c的话&#xff0c; 我所知道的周边的会c的同学&…

[比赛简介]AMP®-Parkinson‘s Disease Progression Prediction

比赛链接&#xff1a;AMP-Parkinsons Disease Progression Prediction | Kaggle 比赛简介 本次竞赛的目标是预测MDS-UPDR评分&#xff0c;该评分衡量帕金森病患者的进展。运动障碍协会赞助的统一帕金森病评定量表&#xff08;MDS-UPDRS&#xff09;修订版是对与帕金森病相关…

使用Charles进行HTTPS抓包

charles安装 下载地址 https://www.charlesproxy.com/download/latest-release/ 我安装的是charles-4.6.4版本 配置手机 注意: 一定要在同一网段 mac电脑的ip地址 手机的ip地址 使用同样的命令 长按配置代理,连接到电脑 此时抓包,会看到一堆unknown, 因为请求的是https…