Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听

马肤
摘要:本教程介绍了Java最新图形化界面开发技术——JavaFx,包括UI控件用法介绍、属性绑定、事件监听和FXML。通过学习本教程,读者可以掌握JavaFx的基本概念和核心技术,学会使用各种UI控件,掌握属性绑定和事件监听机制,以及使用FXML构建Java应用程序界面的方法。本教程为开发者提供了全面的JavaFx开发指南,帮助读者快速入门并提升Java图形界面开发技能。

文章目录

  • 一、JavaFx介绍
    • 1、JavaFx简介
    • 2、可用性
    • 3、主要特征
    • 4、UI控件
    • 二、JavaFx概述
      • 1、JavaFx结构图
      • 2、JavaFx组件
        • (1)舞台
        • (2)场景
          • ① 场景图
          • ② 节点
          • (3)控件
          • (4)布局
          • (5)图表
          • (6)2D图形
          • (7)3D图形
          • (8)声音
          • (9)视频
          • 三、JavaFx快速入门
            • 1、IDEA配置JavaFx环境
            • 2、编码与运行
            • 四、组件功能介绍
              • 1、Application
              • 2、Stage舞台(窗口)
                • (1)创建舞台
                • (2)展示舞台
                • (3)在舞台上设置场景
                • (4)舞台标题
                • (5)舞台位置
                • (6)舞台宽度和高度
                • (7)舞台风格
                • (8)舞台全屏模式
                • (9)阶段生命周期事件
                • (10)键盘或鼠标事件
                • 3、Scene场景
                  • (1)创建场景
                  • (2)在舞台上设置场景
                  • (3)场景鼠标光标
                  • 4、Node节点 UI控件的通用属性
                    • (1)控件节点坐标系
                    • (2)设置控件坐标
                    • (3)设置控件风格
                    • (4)设置控件首要背景宽度和高度
                    • (5)设置文本居中
                    • (6)设置是否显示/隐藏该控件
                    • (7)设置控件半透明值
                    • (8)设置控件旋转角度
                    • (9)设置控件X轴和Y轴平移量
                    • 5、UI控件的属性绑定和属性监听
                    • 6、JavaFx应用里的事件驱动编程
                    • 7、Color、Font、Image
                      • (1)Color颜色
                      • (2)Font字体
                      • (3)Image图片
                      • 五、FXML
                        • 1、FXML布局文件的使用
                        • 2、Scene Builder里构建fxml布局文件
                        • 3、Controller里的initialize方法
                        • 4、在Application里操作Controller
                        • 六、JavaFx多线程操作Platform.runLater

                          JavaFx是Java图形化界面技术AWT、Swing技术的新替代品,如果想系统学习JavaFx,推荐一个B站UP主:https://space.bilibili.com/5096022/channel/collectiondetail?sid=210809
                          如果是想快速入门JavaFx,推荐视频:
                          https://www.bilibili.com/video/BV1H14y1g7ji/
                          https://www.bilibili.com/video/BV1Qf4y1F7Zv/


                          如果你因毕设或项目中用到图形化界面技术JavaFx,赶时间都不想看,请看下面的文字版,通过多个案例,直接带你快速入门JavaFx,轻松上手看懂并学会使用!


                          一、JavaFx介绍

                          1、JavaFx简介

                          JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。
                          JavaFX允许开发人员快速构建丰富的跨平台应用程序。JavaFX通过硬件加速图形支持现代GPU。
                          JavaFX允许开发人员在单个编程接口中组合图形,动画和UI控件。
                          图表编程语言可用于开发互联网应用程序(RIA)。JavaFX技术主要应用于创建Rich internet applications(RIAs)。当前的JavaFX包括JavaFX脚本和JavaFX Mobile (一种运营于行动装置的操作系统),今后JavaFX将包括更多的产品。JavaFX Script编程语言 (以下称为JavaFX) 是一种声明性的、静态类型脚本语言。
                          JavaFX技术有着良好的前景,包括可以直接调用Java API的能力。因为JavaFX Script是静态类型,它同样具有结构化代码、重用性和封装性,如包、类、继承和单独编译和发布单元,这些特性使得使用JavaFX技术创建和管理大型程序变为可能。

                          JavaFx官网:https://openjfx.io/
                          Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第1张
                          下面是基于JavaFx实现的一些第三方开发案例和应用场景:
                          Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第2张

                          2、可用性

                          JavaFX API与Java SE运行时环境(JRE)和Java开发工具包(JDK)绑在一起。
                          JDK可用于所有主要的桌面平台,Windows,Mac OS X和Linux。

                          JavaFX应用程序可以在所有主要的桌面平台上编译和运行。
                          JDK for ARM平台包括JavaFx的基础,图形和控件组件。

                          3、主要特征

                          JavaFX中包含以下功能-

                          • JavaFX是用Java编写的,JavaFX应用程序代码可以从任何Java库引用API。
                          • JavaFX应用程序的外观和感觉可以定制。因此可以使用级联样式表(CSS)来对JavaFX应用程序进行风格化。平面设计师可以通过CSS自定义外观和样式。
                          • 还可以在FXML脚本语言中描述UI的表示方面,并使用Java对应用程序逻辑进行编码。
                          • 通过使用JavaFX Scene Builder,可以通过拖放来设计Ul。Scene Builder将创建可以移植到集成开发环境(IDE)的FXML标记,以便开发人员可以添加业务逻辑。
                          • JavaFX有一个称为WebView的控件,可以呈现复杂的网页。WebView支持JavaScript,我们可以从Java API在Web页面中调用Javascript。 WebView不支持额外的HTML5功能,包括Web套接字,Web Workers和Web字体,还可以从WebView打印网页。
                          • Swing互操作性。现有的Swing应用程序可以使用JavaFX类,例如图表和WebView。还可以使用SwingNode类将Swing内容嵌入到我们应用程序中。
                          • 3D图形功能。JavaFX支持Shape,如Box,Cylinder,MeshView和Sphere子类,SubScene,Material,PickResult,AmbientLight和PointLight。
                          • Canvas API。 使用Canvas API,可以在JavaFX场景上绘制。
                          • 打印APl。 javafx.print包提供了JavaFX Printing API的类。
                          • 富文本支持。JavaFX支持增强的文本,包括双向文本和复杂的文本脚本,例如泰语和印度教的控件,以及多行,多种风格的文本。
                          • 多点触控支持,JavaFX提供对多点触摸操作的支持。
                          • JavaFX支持Hi-DPI显示。

                            4、UI控件

                            以下列出了JavaFX API中提供的一些内置JavaFX UI控件:

                            • Label
                            • Button
                            • Radio Button
                            • Toggle Button
                            • Checkbox
                            • ChoiceBox
                            • Text Field
                            • Password Field
                            • Scroll Bar
                            • Scroll Pane
                            • List View
                            • Table View
                            • Tree View
                            • Tree Table View
                            • Combo Box
                            • Separator
                            • Slider
                            • Progress Bar
                            • Progress Indicator
                            • Hyperlink
                            • Tooltip
                            • HTML Editor
                            • Titled Pane
                            • AccordionMenu
                            • Color Picker
                            • Date Picker
                            • Pagination Control
                            • File Chooser

                              JavaFX允许UI控制节点和形状节点在场景图上共存。
                              我们可以像任何其他JavaFX节点一样处理任何UI控件,例如可以缩放,旋转,样式和添加效果。


                              二、JavaFx概述

                              1、JavaFx结构图

                              一般来说,JavaFX应用程序包含一个或多个对应于窗口的阶段。每个阶段都有一个场景。每个场景都可以有一个控件、布局等附加到它的对象图,称为场景图。这些概念都将在后面更详细地解释。下面是JavaFX应用程序的般结构的图示:
                              Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第3张
                              Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第4张

                              2、JavaFx组件

                              (1)舞台

                              舞台是JavaFX应用程序的外部框架。舞台通常对应于一个窗口。在 JavaFX 可以在浏览器中运行的早期阶段,舞台还可以指网页内 JavaFX 可用于绘制自身的区域。
                              由于 Java 浏览器插件的弃用,JavaFX 主要用于桌面应用程序。在这里,JavaFX 取代了 Swing 作为推荐的桌面GUI 框架。而且JavaFX 看起来比 Swing 更加一致且功能丰富。
                              在桌面环境中使用时,JavaFX 应用程序可以打开多个窗口。每个窗口都有自己的舞台。
                              每个阶段都由StageJavaFX 应用程序中的一个对象表示。StageJavaFX 应用程序有一个由JavaFX 运行时为您创建的主对象。如果 JavaFX 应用程序Stage需要打开其他窗口,它可以创建其他对象。例如,对于对话框、向导等。

                              (2)场景

                              要在JavaFX 应用程序的舞台上显示何内容,您需要一个场景。一个舞台一次只能显示一个场景,但可以在运行时交换场景。就像剧院中的舞台可以重新安排以在戏剧期间显示多个场景一样,JavaFX 中的舞台对象可以在JavaFX 应用程序的生命周期内显示多个场景 (一次一个) 。
                              您可能想知道为什么 JavaFX 应用程序的每个阶段会有多个场景。想象一个电脑游戏。一个游戏可能有多个“屏幕”向用户显示。例如,初始菜单屏幕、主游戏屏幕(玩游戏的地方)、游戏结束屏幕和高分屏幕。这些屏幕中的每一个都可以由不同的场景来表示。当游戏需要从一屏切换到下一屏时,它只需将相应的场景附加到StageJavaFX 应用程序的对象上即可。
                              场景由SceneJavaFX 应用程序中的对象表示。JavaFX 应用程序必须创建Scene它需要的所有对象。

                              ① 场景图

                              所有视觉组件(控件、布局等)都必须附加到要显示的场景,并且该场景必须附加到舞台才能使整个场景可见。附加到场景的所有控件、布局等的总对象图称为场景图。

                              ② 节点

                              附加到场景图的所有组件都称为节点。所有节点都是JavaFX 类的子类,称为javafx.scene.Node。
                              有两种类型的节点:分支节点和叶节点。分支节点是可以包合其他节点(子节点)的节点。分支节点也称为父节点,因为它们可以包含子节点。叶节点是不能包含其他节点的节点。

                              (3)控件

                              JavaFX 控件是 JavaFX 组件,它们在JavaFX 应用程序中提供某种控制功能。例如,按钮、单选按钮、表格、树
                              为了使控件可见,它必须附加到某个Scene对象的场景图中。
                              控件通常嵌套在一些 JavaFX 布局组件中,这些组件管理控件相对于彼此的布局。
                              JavaFX 包含以下控件:

                              • 手风琴
                              • 按钮
                              • 复选框
                              • 选择框
                              • 选色器
                              • 组合框
                              • 日期选择器
                              • 标签
                              • 列表显示
                              • 菜单
                              • 菜单栏
                              • 密码字段
                              • 进度条
                              • 单选按钮
                              • 滑块
                              • 微调器
                              • 拆分菜单按钮
                              • 拆分窗格
                              • 表视图
                              • 选项卡窗格
                              • 文本区域
                              • 文本域
                              • 标题窗格
                              • 切换按钮
                              • 工具栏
                              • 树表视图
                              • 树视图

                                这些控件中的每一个都将在单独的文本中进行解释。

                                (4)布局

                                JavaFX 布局是其中包含其他组件的组件。布局组件管理嵌套在其中的组件的布局。JavaFX 布局组件有时也称为父组件,因为它们包含子组件,而且布局组件是JavaFX 类的子类javafx.scene.Parent。
                                布局组件必须附加到某个Scene对象的场景图才能可见。
                                JavaFX 包含以下布局组件:

                                • 团体
                                • 地区
                                • 窗格
                                • HBox
                                • 盒子
                                • 流窗格
                                • 边框窗格
                                • 边框窗格
                                • 堆栈窗格
                                • 瓷砖窗格
                                • 网格窗格
                                • 锚点窗格
                                • 文本流

                                  这些布局组件中的每一个都将在单独的文本中进行介绍。

                                  (5)图表

                                  JavaFX 带有一组内置的即用型图表组件,因此您不必每次需要基本图表时都从头开始编写图表代码。
                                  JavaFX 包含以下图表组件:

                                  • 面积图
                                  • 条形图
                                  • 气泡图
                                  • 折线图
                                  • 饼形图
                                  • 散点图
                                  • 堆积面积图
                                  • 堆积条形图

                                    (6)2D图形

                                    JavaFX 包含可以轻松在屏幕上绘制2D 图形的功能。

                                    (7)3D图形

                                    JavaFX 包含可以轻松在屏幕上绘制 3D 图形的功能。

                                    (8)声音

                                    JavaFX 包含使在 JavaFX 应用程序中播放音频变得容易的功能。这通常在游戏或教育应用中很有用。

                                    (9)视频

                                    JavaFX 包合使在 JavaFX 应用程序中播放视频变得容易的功能。这通常在流媒体应用程序、游戏或教育应用程序中很有用。

                                    JavaFX 包含一个WebView能够显示网页 (HTML5、CSS 等)的组件。JavaFXWebView组件基于 WebKit-Chrome 和 Safari 中也使用的网页染引擎。
                                    该WebView组件使得将桌面应用程序与 Web 应用程序混合成为可能。有时这很有用。例如,如果您已经有一个不错的 Web 应用程序,但需要一些只有桌面应用程序才能提供的功能一一例如磁盘访问、与 HTTP 以外的其他网络协议 (例如 UDP、IAP 等) 的通信。


                                    三、JavaFx快速入门

                                    JavaFx中文官方网站:https://openjfx.cn/

                                    1、IDEA配置JavaFx环境

                                    JDK8集成了JavaFx,而JDK11后就不自带JavaFx了,需要自己下载jar包进行导入。
                                    如果使用的是Java8,请直接跳到下面第二步。

                                    2、编码与运行

                                    Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第5张
                                    创建以下包目录结构、主入口Main类:
                                    Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第6张
                                    编写一个JavaFx基本结构代码:

                                    import javafx.application.Application;
                                    import javafx.scene.Scene;
                                    import javafx.scene.control.Label;
                                    import javafx.scene.layout.BorderPane;
                                    import javafx.stage.Stage;
                                    // 继承Application抽象类,重新start方法
                                    public class Main extends Application {
                                        public static void main(String[] args) {
                                            // 入口函数里调用Application的静态方法launch,之后会自动调用start方法
                                            Application.launch(args);
                                        }
                                        /**
                                         * @param primaryStage 主窗口
                                         */
                                        @Override
                                        public void start(Stage primaryStage) throws Exception {
                                            // 设置一个场景,场景里添加一个树形组件图,先创建一个标签
                                            Label label = new Label("Hello JavaFx!");
                                            // 创建布局,将标签放入布局里,BorderPane布局把场景划分为上下左右中,默认加入的控件在中间位置
                                            BorderPane pane = new BorderPane(label);
                                            // 创建场景,将布局放入场景里,设置宽度和高度
                                            Scene scene = new Scene(pane, 300, 300);
                                            // 将场景设置到窗口里
                                            primaryStage.setScene(scene);
                                            // 设置标题
                                            primaryStage.setTitle("我是窗口");
                                            primaryStage.show();
                                        }
                                    }
                                    

                                    运行main方法,测试结果:
                                    Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第7张


                                    四、组件功能介绍

                                    1、Application

                                    1. Application是JavaFx程序的入口,任何JavaFx应用程序程序都要继承该类并重写start()方法。
                                    public class Main extends javafx.application.Application {
                                        public static void main(String[] args) {
                                            Application.launch(args);
                                        }
                                        @Override
                                        public void start(Stage primaryStage) throws Exception {
                                        }
                                    }
                                    
                                    1. 通过main()执行Application的launch(String… args)方法,当然该方法不传入任何值也是可以执行的。launch()方法会默认执行本类下的init()、start()、stop()方法。执行下面的main()方法后显示顺序为:
                                    import javafx.application.Application;
                                    import javafx.stage.Stage;
                                    public class Main extends Application {
                                        public static void main(String[] args) {
                                            launch(args);
                                            System.out.println("这是main方法");
                                        }
                                        @Override
                                        public void init() {
                                            System.out.println("这是初始化方法");
                                        }
                                        @Override
                                        public void start(Stage primaryStage) throws Exception {
                                            primaryStage.show();
                                            System.out.println("这是start()方法");
                                        }
                                        @Override
                                        public void stop() throws Exception {
                                            System.out.println("这个是stop()方法");
                                        }
                                    }
                                    

                                    可以看出只有当stop()方法被调用时(即Application应用程序被正常关闭,也可以是图形界面右上角的❌被点击时),launch()方法才执行完毕。(通过Platform.exit()退出界面也是属于正常退出)
                                    通过IDE控制台终止应用程序属于非正常终止,它是通过关闭JVM从而关闭应用程序的。

                                    1. 也可以在其他类中的main()方法中调用launch()方法,但要传入相应的参数,第一个参数指定一个Application的子类,从而调用该类下的init()、start()、stop()方法,第二个参数制定一个String类型的值。

                                    该方法launch(Class


                                    2、Scene Builder里构建fxml布局文件

                                    官方下载链接:https://openjfx.cn/scene-builder/
                                    Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第8张

                                    点击下一步,完成安装
                                    Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第9张

                                    选择空项目
                                    Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第10张

                                    布局和组件直接拖拽进场景即可,保存后可生成对应的fxml文件。
                                    Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第11张


                                    3、Controller里的initialize方法

                                    有时我们是无法在fxml文件里填充数据的,并且有些内容需要初始化时就填充(如表格),而不是触发事件后填充,此时就可以使用initialize方法,做一些初始化的工作。

                                    initialize()方法需要自定义,定义完之后会自动调用,该方法调用的时机是加载好fxml文件,并绑定好控件id之后,才会自动调用一次。

                                    需要注意的是在initialize()方法中是无法访问Scene场景的。

                                    • 演示案例:使用initialize()方法初始化时填充完TableView的数据。
                                      public class Main extends Application {
                                          public static void main(String[] args) {
                                              Application.launch(args);
                                          }
                                          @Override
                                          public void start(Stage primaryStage) throws Exception {
                                              Pane root = FXMLLoader.load(getClass().getResource("hello.fxml"));
                                              primaryStage.setScene(new Scene(root));
                                              primaryStage.show();
                                          }
                                      }
                                      public class Person {
                                          private String name;
                                          private int age;
                                          public Person(String name, int age) {
                                              this.name = name;
                                              this.age = age;
                                          }
                                          public String getName() {
                                              return name;
                                          }
                                          public void setName(String name) {
                                              this.name = name;
                                          }
                                          public int getAge() {
                                              return age;
                                          }
                                          public void setAge(int age) {
                                              this.age = age;
                                          }
                                      }
                                      public class Controller {
                                          @FXML
                                          private TableView tableView;
                                          @FXML
                                          private TableColumn name;
                                          @FXML
                                          private TableColumn age;
                                          
                                          public void initialize() {
                                              ObservableList cellDate = FXCollections.observableArrayList();
                                              name.setCellValueFactory(new PropertyValueFactory("name"));
                                              age.setCellValueFactory(new PropertyValueFactory("age"));
                                              cellDate.add(new Person("张三", 18));
                                              cellDate.add(new Person("李四", 19));
                                              cellDate.add(new Person("王五", 23));
                                              cellDate.add(new Person("赵六", 15));
                                              tableView.setItems(cellDate);
                                          }
                                      }
                                      
                                      
                                      
                                      
                                      
                                         
                                            
                                              
                                                
                                                
                                              
                                            
                                         
                                      
                                      

                                      效果图:
                                      Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第12张


                                      4、在Application里操作Controller

                                      • 案例演示:和之前圆的案例一样,要求圆的中心点自适应边框大小,使用fxml实现。
                                        public class JavaFxApplication extends Application {
                                            public static void main(String[] args) {
                                                launch(args);
                                            }
                                            @Override
                                            public void start(Stage primaryStage) throws IOException {
                                                FXMLLoader fxmlLoader = new FXMLLoader();   // 使用FXMLLoader获取布局里面的Controller的引用
                                                fxmlLoader.setLocation(getClass().getResource("hello.fxml"));
                                                Parent root = fxmlLoader.load();
                                                Scene scene = new Scene(root);
                                                // 在Application中操作Controller进行属性绑定
                                                Controller controller = fxmlLoader.getController();
                                                controller.circleLocationBind(scene);
                                                primaryStage.setScene(scene);
                                                primaryStage.show();
                                            }
                                        }
                                        public class Controller {
                                            @FXML
                                            private Circle ci;
                                            public void circleLocationBind(Scene scene) {
                                                // 获得X和Y中心点的可绑定对象,设置中心点自适应边框大小
                                                ci.centerXProperty().bind(scene.widthProperty().divide(2));
                                                ci.centerYProperty().bind(scene.heightProperty().divide(2));
                                            }
                                        }
                                        
                                        
                                        
                                        
                                           
                                              
                                           
                                        
                                        

                                        效果图:
                                        Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第13张

                                        Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第14张


                                        六、JavaFx多线程操作Platform.runLater

                                        当我们执行一些耗时操作时,如加载资源。我们为了防止这些耗时操作占用JavaFx的主线程资源,下面的代码无法执行造成软件界面加载卡顿,我们通常使用JavaFx支持的多线程操作来解决这个问题。

                                        • 案例演示1:使用多线程技术实现点击Button按钮获取姓名数据(模拟数据库获取数据)显示在Label文字布局上。
                                          public class Main extends Application {
                                              public static void main(String[] args) {
                                                  launch(args);
                                              }
                                              @Override
                                              public void start(Stage primaryStage) throws Exception {
                                                  Label label = new Label("姓名是?");
                                                  label.setLayoutX(200);
                                                  label.setLayoutY(350);
                                                  Button button = new Button("点击获取姓名");
                                                  button.setLayoutX(200);
                                                  button.setLayoutY(400);
                                                  button.setOnAction(event -> {
                                                      new Thread(() -> {
                                                          String name = "Aizen";	// 模拟数据库获取值的操作,这里直接定义
                                                          label.setText(name);	// 更新UI控件的操作
                                                      }).start();
                                                  });
                                                  AnchorPane pane = new AnchorPane();
                                                  pane.getChildren().addAll(label, button);
                                                  Scene scene = new Scene(pane, 500, 500);
                                                  primaryStage.setScene(scene);
                                                  primaryStage.show();
                                              }
                                          }
                                          

                                          如果直接这样运行,点击后会报出非法状态异常,不在JavaFx的Application线程中,更新UI控件必须在Fx Application主线程中。
                                          Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第15张

                                          想要避免这个问题,需要使用到JavaFx提供的静态方法Platform.runLater(Runnable runnable),其中参数需要一个Runnber对象,runLater方法将Runnable放在任务队列里面,在Application线程空闲的时候,会执行队列里的任务。

                                          public class Main0 extends Application {
                                              public static void main(String[] args) {
                                                  launch(args);
                                              }
                                              @Override
                                              public void start(Stage primaryStage) throws Exception {
                                                  Label label = new Label("姓名是?");
                                                  label.setLayoutX(200);
                                                  label.setLayoutY(350);
                                                  Button button = new Button("点击获取姓名");
                                                  button.setLayoutX(200);
                                                  button.setLayoutY(400);
                                                  button.setOnAction(event -> {
                                                      // 报错案例:
                                                      /*new Thread(() -> {
                                                          String name = "Aizen";  // 模拟数据库获取值的操作,这里直接定义
                                                          label.setText(name);    // 更新UI控件的操作
                                                      }).start();*/
                                                      
                                                      // 正确案例:
                                                      // runLater方法将Runnable放在任务队列里面,在Application线程空闲的时候,会执行队列里的任务
                                                      new Thread(() -> {
                                                          String name = "Aizen";  // 模拟数据库获取值的操作,这里直接定义
                                                          Platform.runLater(() -> {
                                                              label.setText(name);    // 更新UI控件的操作
                                                          });
                                                      }).start();
                                                  });
                                                  AnchorPane pane = new AnchorPane();
                                                  pane.getChildren().addAll(label, button);
                                                  Scene scene = new Scene(pane, 500, 500);
                                                  primaryStage.setScene(scene);
                                                  primaryStage.show();
                                              }
                                          }
                                          

                                          效果图:
                                          Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第16张

                                          Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML),Java最新图形界面开发技术,JavaFx教程全解析——从UI控件到FXML与事件监听 第17张

                                          其实在JavaFx很多控件的事件里面都内部调用了runLater()方法,比如下面这个案例:

                                          • 案例演示2:使用多线程技术实现点击Button按钮通过url加载图片,并显示图片和加载进度(模拟耗时操作)。
                                            public class Main1 extends Application {
                                                public static void main(String[] args) {
                                                    launch(args);
                                                }
                                                @Override
                                                public void start(Stage primaryStage) throws Exception {
                                                    ImageView imageView = new ImageView();
                                                    imageView.setLayoutX(100);
                                                    imageView.setLayoutY(20);
                                                    Label label = new Label();
                                                    label.setLayoutX(400);
                                                    label.setLayoutY(350);
                                                    Button button = new Button("点击获取图片");
                                                    button.setLayoutX(400);
                                                    button.setLayoutY(410);
                                                    button.setOnAction(event -> {
                                                        // 通过url加载图片,这种操作可能会比较耗时通常会另开一个线程去执行,而不占用主线程
                                                        Thread thread = new Thread(() -> {
                                                            Image image = new Image("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F0a0caee4-4afd-4fbf-bcf8-8269315c7915%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715148006&t=f254957770daea43b9b1f4cdb6c2c987", true);
                                                            // 该监听器的changed方法在底层已经封装了Platform.runLater()方法
                                                            image.progressProperty().addListener(new ChangeListener() {
                                                                @Override
                                                                public void changed(ObservableValue

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码