JavaFX 是一个开源的下一代客户端应用平台,适用于基于 Java 构建的桌面、移动端和嵌入式系统。 它以 Java 为基础构建,旨在创建具有现代、硬件加速用户界面的高性能、可携带的富客户端应用。 1. 现代用户界面 采用先进的图形渲染引擎和丰富的 UI 控件,可创建具有现代感的用户界面。这些 UI 控件包括各种布局容器、按钮、文本框、列表视图等,支持 CSS 样式和自定义皮肤,能够满足不同应用的界面需求。 2. 硬件加速 充分利用现代图形硬件的加速能力,提高图形和动画的渲染性能,使应用能够提供更流畅的视觉效果和更复杂的交互体验。 3. 支持跨平台 基于 Java 的跨平台特性,JavaFX 应用可以在多个操作系统上运行,如 Windows、macOS、Linux 等,确保应用的一致性和可移植性,可以从官网上下载对应版本和系统的 sdk,官网网址:https://gluonhq.com/products/javafx/ 4. CSS 样式支持 通过 CSS 定制控件外观,实现主题切换和现代化设计。 5. 模块化设计 JavaFX 采用模块化架构,将功能划分为多个模块,如 javafx.scene、javafx.controls、javafx.fxml 等。开发者可以根据应用需求选择所需的模块,减少不必要的依赖。 6. 丰富的媒体支持 集成了对音频、视频、图像等多媒体内容的播放和支持,支持 Web 内容嵌入和视频/音频播放(MediaPlayer、MediaView),也支持对 H.265/HEVC 等视频编码格式,可实现各种媒体功能。 7. 响应式设计 内置布局管理器(VBox、BorderPane 等)用于适配不同分辨率,绑定 API 实现数据可以实现和 UI 的自动同步(如 Property 与 Binding)等功能。 8. 社区支持 JavaFX 拥有一个活跃的开发者社区,社区成员积极参与开发和维护,提供各种工具和框架来扩展 JavaFX 的功能。 桌面应用开发:JavaFX 的跨平台特性和丰富的 UI 控件使其成为开发桌面应用的理想选择,如办公软件、图像处理工具、媒体播放器等。 企业应用:可用于构建企业级的富客户端应用,如金融分析软件、企业资源管理(ERP)系统、客户关系管理(CRM)系统等,提供高效的数据展示和交互功能。 嵌入式系统:凭借其高效的性能和可定制性,适用于嵌入式设备,如智能电视、工业控制系统、医疗设备等,为这些设备提供图形用户界面。 媒体播放器:JavaFX 支持音频、视频、图像等多媒体内容,适用于教育、科学等方面,可以提高页面展示。 JavaFX 的基础模块涵盖了从窗口管理、场景图、布局、控件、事件处理、属性绑定到样式和动画等多个方面。它提供了现代化的 API 和丰富的功能,使得开发复杂的桌面应用变得简单高效。 提示:从 JDK 11 开始,JavaFX 作为独立模块分发(需单独从官网上下载 sdk) Application 作为核心类,是所有 JavaFX 应用的入口类,管理 JavaFX 应用的生命周期 init()、start()、stop(),示例如下: Stage 管理窗口属性(标题、尺寸、全屏等),Scene 是内容容器,存放所有 UI 组件绑定到 Stage,示例如下: javafx.scene.Parent 是所有 JavaFX 场景图(Scene Graph)中的根节点,不能直接实例化,常见子类有 Group、Region、各种布局面板(如 StackPane等),示例如下: 常用控件:Button, Label, TextField``CheckBox, RadioButton、ComboBox, ListView, TableView 布局管理器(Layouts) 核心布局: HBox/VBox:水平/垂直排列组件 BorderPane:上、下、左、右、中五区域 GridPane:网格布局(类似 HTML 表格) FlowPane:自动换行布局 示例: 可以使用可视化拖拽工具(Scene Builder)快速生成 FXML 文件,然后可以通过 FXMLLoader.load() 方法加载 FXML 文件,将 FXML 文件解析为 JavaFX 的节点树(Parent),实现界面与逻辑的分离。 使用 idea 创建一个 javaFX 项目; 从 JavaFX 官网上下载 JavaFX SDK 并解压,然后在 File -> Project Structure -> Libraries -> + → 选择 JavaFX SDK 的 lib 目录下所有 jar 包,如图所示: 在项目中的 src/main/java/包名/Main.java 里编写 JavaFX 启动代码,参考所示: 1. 点击 Edit Configurations...,在 Build and Run 里配置 jdk 版本; 2. 在 VM options 中添加如下: 其中 --module-path 是指 javaFX sdk 的路径,--add-modules 是指依赖的模块,配置如图所示: 运行项目能看到 JavaFX 窗口弹出,如图所示: 1. Java 源代码(.java)经过编译后变成字节码(.class),但字节码仍然保留了大量的结构化信息,如类名、方法名、字段名、常量、注释等。 2. 字节码是为 JVM 设计的"中间代码",不是机器码,可读性较高; 3. 目前市面上有很多成熟的 Java 反编译工具(如 JD-GUI、Jadx 等),反编译工具利用字节码中的结构信息,可以几乎无损地将 .class 文件还原为可读的 Java 源代码。 Virbox Protector 工具对 Java 有着成熟的保护方案,包括 Java BCE 和 Java VME 方式两种,其中 Java BCE 方式是对 class 中的所有⽅法的字节码加密,性能好兼容性高,而 Java VME 方式是将JVM字节码转换为自定义的虚拟机指令进行保护,安全性极高。 Java BCE 方式是完全支持 JavaFX 程序的保护; Java VME 方式会受到 JavaFX 的调用机制,如果函数全选代码虚拟化后,程序无法运行,所以在使用Java VME 方式时需要注意以下事项。 使用 Java VME 方式保护,如果对 jar 包内所有函数全选代码虚拟化后,程序无法运行,会报错如下信息: Exception in thread "main" java.lang.reflect.InvocationTargetException, Caused by: java.lang.RuntimeException: Error: class CC000000686383760012EABABDA4A9BE is not a subclass of javafx.application.Application" JavaFX的调用机制 首先,我们先了解下 javafx.application.Application.launch() 的调用机制。 Application.launch() 是 JavaFX 应用的启动入口,它会初始化 JavaFX 运行环境,并最终调用你自定义的 Application 子类的 start (比如 Stage primaryStage ) 方法。 当调用 Application.launch() 时,JavaFX 会检查调用它的类(即调用栈中的主类)是否继承javafx.application.Application 如果主类没有继承自 Application,JavaFX 无法正确启动应用,也无法保证生命周期的完整性,所以程序会报异常。 这也是 JavaFX 区别于普通 Java 程序的一个标志,只有继承了 Application 的类,才能作为 JavaFX 应用的入口。 问题排查 我们先看一下关于 Application.launch() 的 Main 函数虚拟化后和原程序时的反编译效果图: 原程序 Main 函数反编译,如图所示: 这是 Main 虚拟化的结果,如图所示: 就是因为 launch() 被虚拟化了,然后被 Vibox 壳的类加载器给替代了,所以导致找不到应用的启动入口,进而启动时报错。 问题解决方案 对于以上的问题,有两种处理方案,分别如下: 如果使用 Java VME 方式,最好的处理方案就是 main 函数不要进行代码虚拟化,其他函数不受限制。 使用 Java BCE 方式,该方式完全无上述问题限制。 END 👇扫码进群,一起畅聊技术,共享前沿资讯! 👇点击关注,🌟星标深盾,了解更多精彩内容!import javafx.application.Application;
public class Main extends Application {
public void start(Stage primaryStage) throws Exception {
//ui代码
}
public static void main(String[] args) {
launch(args);
}
}
import javafx.scene.Scene;
import javafx.stage.Stage;
Scene scene = new Scene(root, 300, 300); // 场景
primaryStage.setTitle("First App");
primaryStage.setScene(scene);
primaryStage.show();
import javafx.scene.Parent;
//引用sample.fxml页面布局
Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("sample.fxml")));
import javafx.scene.control.Button;
Button btn = new Button("点我");
btn.setOnAction(e -> System.out.println("Hello JavaFX!"));
BorderPane root = new BorderPane();
root.setTop(new Label("Header"));
root.setCenter(new Button("Center"));
import javafx.fxml.FXMLLoader;
Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("sample.fxml")));
package org.example;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
public void start(Stage primaryStage) throws Exception {
Button btn = new Button("点我!");
btn.setOnAction(e -> System.out.println("Hello JavaFX!"));
StackPane root = new StackPane(btn);
Scene scene = new Scene(root, 300, 300); // 场景
primaryStage.setTitle("First App");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
--module-path "F:\SoftTools\javafx-sdk-21.0.7\lib" --add-modules javafx.controls,javafx.fxml,javafx.web
JavaFX 程序的介绍和安全防范
本文来自投稿,不代表本站立场,如若转载,请注明出处:https://blog.firsource.cn/news/1397.html