最近在考虑开发GUI
程序,由于用Java
比较多,就想试试看Java
开发GUI
程序是否可行,用JavaFX
实现一个计算器demo
程序。
JavaFX
是目前比较流行的Java GUI
开发框架,使用fxml
作为布局文件,通过JavaFX Scene Builder
可以实现拖动布局等,方便构建程序。
源码地址:https://github.com/fugary/javafx-demo
新建项目
用idea
新建JavaFX
项目还是比较容易的,不用第三方库,用原生的就可以,这里最低要求JDK11
。
目前就可以运行了,简单hello程序。
实现程序
使用重构器(Shift+F6
)修改基本文件名称,改为自己使用的名称:
布局处理
如果没有安装JavaFX Scene Builder
,可以根据提示安装,安装后可以用它现实布局。
目前用GridPane
布局,实现6
行4
列的格子,每个格子100*100
大小:
第一行用文本框,实现数字显示和计算结果显示,后面几行显示计算器的各种按钮,调整下大小:
基本结构算是有了
样式处理
新建一个calc.css
文件,写入按钮样式:
.grayButton{
-fx-background-radius: 45px;
-fx-background-color: #A4A4A4;
}
.yellowButton{
-fx-background-radius: 45px;
-fx-background-color: #F79F31;
}
.normalButton{
-fx-background-radius: 45px;
-fx-background-color: #333333;
}
引入样式,浏览到新定义的calc.css
文件。
引入之后,给按钮配置上样式的class,效果更好一点
实现功能
目前使用一个List
存储临时数据,用一个Stack
存放参与计算的数据,实现简单的计算逻辑,下面是代码片段:
private static final List<String> TEXT_LIST = new ArrayList<>();
private static final Stack<String> CALC_STACK = new Stack<>();
@FXML
private TextField resultText;
public void onNumberButtonClicked(ActionEvent event) {
Button numButton = (Button) event.getSource();
String text = numButton.getText().trim();
// 数字按钮处理
}
然后给每个按钮添加事件实现
具体实现可以参考GitHub源码:https://github.com/fugary/javafx-demo
运行程序
运行程序可以执行简单计算,因为只是一个demo
,并不是完整的程序,可能存在一些bug
,有兴趣可以完善代码。
打包程序
默认生成项目的时候已经有打包插件了:
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.fugary.javafxdemo/com.fugary.javafxdemo.CalcApplication</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
打包压缩
打包命令:
mvn javafx:jlink
打包后可以看到有个app
目录,以及一个压缩包app.zip
:
app
文件夹下面的bin/app.bat
就是可以执行的文件,执行后可以看到结果。
打包exe
使用bat
文件启动会带起一个命令行窗口,关闭命令行窗口的话程序也跟着结束了,其实可以打包成exe
,需要使用jpackage
命令,这个命令是在jdk
中,需要用到前面jlink
打包出来的原始文件夹,命令输出的相当于安装后的目录,已经可以分发使用了。
# 构建exe目录
# --name 指定应用名称
# -m指定为pom.xml中的MainClass
# --runtime-image 指定jlink打包出来的目录】
# --dest 是输出目录
jpackage --type app-image --name MyCalc -m com.fugary.javafxdemo/com.fugary.javafxdemo.CalcApplication --runtime-image target/app --dest target/app-image
打包安装包
文件夹不便于分发安装和卸载,一般程序都是有个安装程序,我们也可以考虑打包成安装包,安装包打包过程比较麻烦。
首先需要安装WiX Toolset,需要使用3.x版本,不支持4.x版本:https://wixtoolset.org/docs/wix3/:
下载地址:https://github.com/wixtoolset/wix3/releases/tag/wix3112rtm
否则会有错误信息:
[12:12:30.011] 找不到 WiX 工具 (light.exe, candle.exe)
[12:12:30.011] 从 https://wixtoolset.org 下载 WiX 3.0 或更高版本,然后将其添加到 PATH。
错误:类型 [exe] 无效或不受支持
如果安装后还是不行,可以考虑把安装后的bin
放到Path
中。
添加到Path
中后,用命令行执行:light --help
有结果输出就对了:
打包成安装包:
# 根据前面产生的目录target/app-image/MyCalc生成一个安装包,注意包含MyCalc这一级,否则报错找不到.jpackage.xml
jpackage --name MyCalcInstaller --app-image target/app-image/MyCalc --dest target/dist --win-dir-chooser --win-shortcut --win-shortcut-prompt
另外会出现311 code
错误:
java.io.IOException: Command [C:Program Files (x86)WiX Toolset v3.11binlight.exe, -nologo, -spdb, -ext, WixUtilExtension, -out, C:UsersmengAppDataLocalTempjdk.jpackage929124607728456094imageswin-exe.imageMyCalcInstaller-1.0.msi, -s
ice:ICE27, -loc, C:UsersmengAppDataLocalTempjdk.jpackage929124607728456094configMsiInstallerStrings_en.wxl, -cultures:en-us, C:UsersmengAppDataLocalTempjdk.jpackage929124607728456094wixobjmain.wixobj, C:UsersmengAppDataLocal
Tempjdk.jpackage929124607728456094wixobjbundle.wixobj, C:UsersmengAppDataLocalTempjdk.jpackage929124607728456094wixobjui.wixobj] in C:UsersmengAppDataLocalTempjdk.jpackage929124607728456094imageswin-msi.imageMyCalc exited with 311 code
增加--verbose
可以看到详细信息,字符问题:
[14:23:31.739] Output:
C:UsersmengAppDataLocalTempjdk.jpackage4320797721992788226configmain.wxs(36) : error LGHT0311 : A string was provided with characters that are not available in the specified database code page '1252'. Either change these characters to ones that exist in the database's code page, or update the database's code page by modifying one of the following attributes: Product/@Codepage, Module/@Codepage, Patch/@Codepage, PatchCreation/@Codepage, or WixLocalization/@Codepage.
C:UsersmengAppDataLocalTempjdk.jpackage4320797721992788226configmain.wxs(79) : error LGHT0311 : A string was provided with characters that are not available in the specified database code page '1252'. Either change these characters to ones that exist in the database's code page, or update the database's code page by modifying one of the following attributes: Product/@Codepage, Module/@Codepage, Patch/@Codepage, PatchCreation/@Codepage, or WixLocalization/@Codepage.
不过这个问题不是我们项目字符有问题,暂时没有想到怎么解决,不过把Windows切换到英文版系统就正常打包了。
打包成了安装包,安装包和压缩包差不多大,双击可以安装:
结束语
目前JavaFX
实现程序倒是很简单,不过打包后比较大,感觉不是很适合开发GUI
程序,一个这么简单的程序打包成zip
后也有26MB
左右,解压后有79MB
。
不过Java
有跨平台的优势,不同平台需要重新打包,也不知道JavaFX
未来是否有发展。