JavaFX是Java的新兴GUI框架,界面比Swing更加友好一些,语法也很简单。软件工程大作业非常推荐用JavaFX换掉Swing,写起来会容易一点。
Maven管理Java项目,尤其是Spring项目,非常好用,可惜自己在上完Java课之后没好好学习这个重要的项目管理工具。之前在软工写大作业的时候用的是IDEA自带的项目结构,配置JavaFX非常复杂,用Maven的包也很麻烦,现在把之前的大作业升级成了Maven框架,编译、运行乃至Junit测试,都是一行简单的命令都可以完成的。在介绍JavaFX和Maven这对绝配组合之前,我先说一下我们组怎么编译JavaFX项目的。
命令行编译运行
JavaFX在JDK11之后就不属于JDK的一部分了,单独由开源社区进行维护。JDK11引入了module的概念,而JavaFX的SDK就是以module的形式提供了Jar包和JMod(用来生成自定义的JRE环境),具体可以查看廖雪峰的这篇。
所以简单版本的编译命令根据JavaFX的教程,长这个样子:
1 | // 编译 |
这里的JavaFX SDK的路径是根据我自己电脑来指定的,因为路径中有空格所以加上了双引号,后面加入了javafx.controls的模块。如果要用fxml的话要加入javafx.fxml的模块;要放视频的话要加入javafx.media的模块。
如果不用第三方库的话手写命令行也无妨,但一旦引入第三方库,比如fasterxml,得在classpath中加入,很麻烦,包多了容易错。
Maven来救命
Maven管理第三方包多的项目很方便。 如果是新项目可以直接按照上面IDEA的JavaFX教程,一口气能把下面的工作做完。
由于我们之前用的不是Maven,就只能手动配置了。先点击项目,add framework升级为Maven,可以参考这篇。然后根据JavaFX的官方Maven教程,首先在项目的pom.xml中加入JavaFX的Maven插件,这个负责的是编译和运行部分,它帮我们配置好了路径,后面我们一句简单的命令就可以直接运行。
1 | <build> |
然后我们需要加入JavaFX的组件,也就是上面我们提到的module。这里我加入了javafx.controls和javafx.media两个组件,在maven中是依赖(dependency)。这里要注意的是,Windows和Linux可以用LTS的11版本,macOS请用17版本,不然字体会乱码。还有一个比较有意思的是Ubuntu视频会放不出来,这个Bug被吐槽了很久还是没修好。
1 | <dependencies> |
最后我们只需要一行mvn clean javafx:run
就可以运行了。如果是IDEA的话在maven配置中去掉mvn就行。
JUnit测试
如果是手动写命令行的话,JUnit测试也是非常麻烦,如果有很多测试的话手写命令行基本上没法弄。但是对于maven这实在是太简单了,把JUnit测试放在test/java文件夹,输入mvn test,一口气跑完所有的测试。
静态资源
JavaFX有css或者fxml文件,这些文件不能直接放在Java文件夹下,编译时会被忽略掉。要放在Resources文件夹下,编译时会被复制到classpath的根目录。这里我在resources文件夹下放了两个文件夹,一个放css,一个放图片。
写路径的时候,比如在resources下面的css文件夹中新建了一个hello.css文件,那导入时路径写成:”/css/hello.css”。因为这个时候java下面的包和resources下面的文件夹会被放到classpath路径中。
JavaFX读取静态资源范例如下。Main.class也可以换成getClass()。
1 | ImageView backgroundImage = new ImageView( |
视频有一点特殊,JavaFX的Media库只支持输入URL路径(本地或者网络),不支持输入流,所以不能放resources文件夹下。我们放项目项目目录data文件夹。
json和txt等文件也不能放resources文件夹,放在代码外面,我们同样放置在项目目录的data文件夹。
发布
JavaFX的发布有一点麻烦。问题出在开头说的,现在的JRE缺少JavaFX的运行时,直接打一个Jar包发给别人,是不能运行的,会出现以下的提示。
错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序
一个解决方案就是自己打包一个JRE,然后和jar包一起发布。
自定义JRE
利用jlink我们可以自定义一个JRE,让其中拥有JavaFX的运行时。
首先去下载JavaFX的jmod。下载页面默认只提供最新的支持版本的包。点选Include older versions的选择框,然后翻到下面选择JavaFX 11或者JavaFX 17的jmod压缩包下载。JavaFX现在只有最新版提供免费的支持,像11或者17现在的LTS包得掏钱买支持,不过对于写大作业的大学生来说是不是最新版没差。
压缩包解压后把jmod包放到Java文件夹下的jmods文件夹。拿Java 11举例子。
然后在JavaFX的项目目录运行以下的命令。%JAVA_HOME%指的是Java的安装文件夹路径,可能需要在Windows环境变量中设置。Linux和macOS改为$JAVA_HOME或者直接替换为绝对路径。add-modules根据自己的项目需要增减。output表示输出的文件夹名称。
jlink --module-path "%JAVA_HOME%\jmods" --add-modules java.base,java.desktop,java.xml,javafx.base,javafx.graphics,javafx.media,jdk.jsobject,jdk.xml.dom,javafx.controls --output jre
运行之后会在项目目录新增一个名为jre的自定义jre环境。记得在gitignore中加入这个文件夹。
打包jar
直接打包mvn clean package
打包是不行的,因为第一没有指定主类,第二是没有打包依赖。
对上面的的maven配置进行修改,增加以下plugin标签,参考。
1 | <plugin> |
然后运行mvn clean package即可同时在target文件夹下得到主程序jar包和lib文件夹。lib文件夹里的是依赖jar包。
在项目目录输入以下命令即可运行jar包,jar包名字自行修改。
jre/bin/java.exe -jar target/your-application.jar
如果嫌开命令行麻烦的话可以写个脚本,或者拿C语言写个启动程序。
发布和压缩
target文件夹下可以只保留主程序jar包和lib文件夹,其他都可以删掉。然后拷贝target, jre和data文件夹到一个单独的文件夹,然后压缩这个文件夹即可。用户收到压缩包后解压,然后在文件夹运行上述命令即可运行。我们组的程序连带JRE压缩后为75M。
小结
Maven还是挺好用的,能够工程化地去编译、测试和打包Java程序,而不用手写命令,好评。
JavaFX框架实话说,已经脱离时代了。桌面端软件现在很多拿网页框架来做,比如flutter或者electron,JavaFX这种玩具未来注定会被淘汰。