# lab-JavaFx **Repository Path**: notar_development_group/lab-java-fx ## Basic Information - **Project Name**: lab-JavaFx - **Description**: JAVAFX 桌面开发框架 - **Primary Language**: Kotlin - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 10 - **Forks**: 2 - **Created**: 2021-09-17 - **Last Updated**: 2024-12-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: Javafx, bytebuddy, Kotlin ## README # LabmemFX ## 描述 框架设计思路根据大佬的 Biubiuyuyu/JavaFX-Plus 的一些实用的方法搭建,因为大佬咕咕就自我实现适合自己的框架 目的简化javafx开发 ### 环境 依赖 [IDEA] [jdk 17] [openjfx 19] [编程语言:Kotlin] [UI库引用:materialfx、bootstrap] [控件库引用:controlsfx] [工具依赖: Hutool、bytebuddy等] [核心包:fx-core] ## 已实现的功能 ### 项目入口 FXAppLauncher是你的程序Application所在的类 companion object { @JvmStatic fun main(args: Array) { FXApplication.run(FXAppLauncher::class.java, args) } } FXAppLauncher 需继承JAVAFX:Application并注解@LabFXApplication 扫描当前类包路径 或 @LabFXApplication(["com.labmem.modular"]) 去扫描包注册controller @LabFXApplication class FXAppLauncher : Application() { override fun start(primaryStage: Stage) { FXApplication.start(primaryStage) FXApplication.close { //正常关闭程序后执行 Console.log("程序关闭啦!") } } } FXApplication是框架启动入口start开始启动主窗口 close方法结束程序也可以传结束前回调 ### 注解 @LabFXApplication 框架扫描入口 @FXController 定义窗口Controller @FXLoadController 定义加载框窗口,需@FXController @FXAspect 指定Controller的切面(只对非FXML controller有效),需@FXController @FXRedirect 方法重定向Controller(只对非FXML controller有效),需@FXController ### 使用示例 #### Controller 控制器 @FXController( fxmlPath = "fxml/main.fxml", //fxml的resources路径(可空,为空时创建非fxml Controller),**[fxml必须以Pane为根控件,不用填写controller]** title = "hello world", //stage title(可空) icon = "icon.jpg", //icon的resources路径(可空) main = true, //是否为主程序启动的窗口(默认 false) tray = false, //当前窗口是否需要系统托盘(默认 false) myTray = MyTray::class, //当需要系统托盘时可自定义托盘(可空,默认托盘) loadContrName = "AppLoadingController", //跳转当前窗口显示前的加载窗口类名(可空) only = false, //唯一窗口,只显示一个并只创建一次 ) class MainController : BaseController() { //以@FXController注册controller时一定继承BaseController override fun initialize() { //可重写fxml加载初始化模块 } override fun initStage() { //可重写【controller初始化执行,用于设计stage】 //初始化后会注入 root:Pane=根控件 stage:Stage=当前窗口 request:FXRedirectParam?=重定向过来的参数 loading:Loading=lab载入框工具 alert:AlertUtil=lab弹窗工具 //甚至可以操作重定向之前的控制器,去修改它的控件的骚操作 val testStage=request.redirectController as TestSatge testStage.textFie1?.let{ it.text="你好" } } override fun onShow() { //展示前执行,用于业务逻辑(ps:使用的渲染主线程,若异步逻辑请使用协程避免阻塞) } } #### FXLoadController 加载窗 @FXController(title = "App Loading..", icon = "icon.jpg") @FXLoadController //加载窗所需的注解,其余和普通controller一样 class AppLoadingController : BaseController() { override fun loadingInit() { //可重写加载方法,因为是加载框肯定需要加载东西,就写这里。该方法完成后关闭加载窗跳转原目标窗口 request:FXRedirectParam?=也能获取到重定向到窗口的参数,以便处理 Thread.sleep(2000) } } #### Tray 自定义托盘 class MyTray : SystemTrayInterFace() { //自定义托盘需要实现SystemTrayInterFace接口 override fun listen(controller: BaseController) { //并重写listen方法以便去监听操作这个窗口,甚至不用托盘,去实现其他操作窗口的工具 } } #### @FXAspect Aop(~~只对非FXML controller有效~~ 新版本已支持FXML的动态代理) class MainAspect : BaseFXAspect() { //切面需继承BaseFXAspect //就能重写以下方法 override fun before(target: Any, method: Method, args: Array?): Boolean override fun after(target: Any, method: Method, args: Array?, returnVal: Any?): Boolean open fun afterException(target: Any, method: Method, args: Array?, e: Throwable?): Boolean } @FXController() //一定是非FXML controller @FXAspect(MainAspect::class) //就能注册上面的切面了 class TestStage :BaseController(){} #### 重定向 【FXML controller】 可以使用父类的redirect()方法 val test = FXRedirectParam(TestStage::class) //创建FXRedirectParam对象,重定向控制器可传String或KClass test.addParams("msg", "hello") //FXRedirectParam是类型 test.addParams("back", { //甚至可以传个回调函数 AlertUtil().successAlert() }) test.ownerRedirect = true //跳转的窗口是否为当前的子窗口(包括在当前窗口内),默认为true input1?.let { test.addParams("input", it) } //也可以传fxml控件,到目标控制器可操作性 redirect(test) 另一种选择@FXRedirect @FXML @FXRedirect //可直接在任意方法使用注解 fun open(event: ActionEvent):FXRedirectParam{//返回类型为FXRedirectParam return FXRedirectParam("TestStage") } #### 工具(xyz.labmem.core.util) 1、ResourceFile 基于hutool获取resources文件和当前运行的路径(包括打包后jar包路径) 2、WindowPointerTool 获取stage窗口在windows下的句柄,用于c++嵌入渲染 3、xyz.labmem.core.util.gui 弹窗、加载、托盘等工具 ## ~~使用graalvm编译器打包(将实现)~~ ### 桌面端 #### 首先初始化x64编译环境 call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" Run the application on JVM/HotSpot: mvn gluonfx:run Run the application and explore all scenarios to generate config files for the native image with: mvn gluonfx:runagent Build a native image using: mvn gluonfx:build Run the native image app: mvn gluonfx:nativerun ### 安卓 Build a native image for Android using: mvn gluonfx:build -Pandroid Package the native image as an 'apk' file: mvn gluonfx:package -Pandroid Install it on a connected android device: mvn gluonfx:install -Pandroid Run the installed app on a connected android device: mvn gluonfx:nativerun -Pandroid ### iOS Build a native image for iOS using: mvn gluonfx:build -Pios Install and run the native image on a connected iOS device: mvn gluonfx:nativerun -Pios Create an IPA file (for submission to TestFlight or App Store): mvn gluonfx:package -Pios ## PS:当高版本JDK反射FXML为null指针报错,需在VM options加上 --add-opens java.base/java.lang.reflect=ALL-UNNAMED