入门JavaFX遇到的一些坑

前言

JavaFX是一个优秀的GUI工具包。用JavaFX编写的应用程序可以跨多个平台一致运行,如:Linux、Mac、iOS、Android等。 以下是关于JavaFX的一些重要特性:

  • 使用Java语言编写 - JavaFX库都是用Java编写的;
  • FXML - FXML是一种类似于HTML的语言,用于快速的构建UI界面;
  • Scene Builder - JavaFX提供了该应用程序(类似于iOS中的StoryBoard),可以直接拖拽UI控件,最终这些UI控件的布局会生成一个.fxml的文件,我们只需加载.fxml文件即可显示UI界面,非常的方便;
  • 丰富的API集合 - JavaFX库提供了一组丰富的API来开发GUI程序,这套API还包括Java平台的功能。比如多线程和Lambda表达式等;

0x1. Scene Builder 安装

Scene Builder下载地址: https://gluonhq.com/products/scene-builder/

如果.fxml文件中引入了第三方jar包的话,用Scene Builder打开.fxml文件时会出现以下异常:

java.io.IOException: javafx.fxml.LoadException:
at com.oracle.javafx.scenebuilder.kit.fxom.FXOMLoader.load(FXOMLoader.java:92)
at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.<init>(FXOMDocument.java:80)
at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.<init>(FXOMDocument.java:95)
1
2
3
4

解决办法:

  1. 将你引入的第三方jar包,粘贴到Scene Builder应用程序 -> Contents -> Java目录下;
  2. app.classpath=xxx.jar文本内容(xxx替换成你的jar包名),编辑到Scene Builder -> Contents -> Java -> ScheneBuilder.cfg文件中。

ScheneBuilder.cfg文件内容如下:

[Application]
app.name=SceneBuilder
app.version=11.0.0
app.preferences.id=com/oracle/javafx/scenebuilder/app
app.runtime=$APPDIR/PlugIns/Java.runtime
app.identifier=com.oracle.javafx.scenebuilder.app
app.classpath=xxx.jar // 新增的内容
app.classpath=scenebuilder-11.0.0-all.jar
app.application.instance=multiple
app.mainjar=scenebuilder-11.0.0-all.jar
app.mainclass=com/oracle/javafx/scenebuilder/app/SceneBuilderApp
jpackager.java.version=11.0.1

[JVMOptions]
--add-opens
javafx.fxml/javafx.fxml=ALL-UNNAMED

[ArgOptions]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

0x2. 打包成Mac App

  1. 在IntelliJ IDEA中,打开 File -> Project Structure -> Artifacts -> 右侧面板中的Java FX选项,将该面板下的Native bundle 修改为image
  2. 在IntelliJ IDEA中,选择 Build -> Build Artifacts...,在弹出的菜单中选择build,即可自动打包成Mac App.

0x3. Java获取本机IP地址方式

最初使用如下方式获取IP地址:

static public String localIPAddress() {
    String ip = null;
    try {
        InetAddress address = InetAddress.getLocalHost();
        ip = address.getHostAddress();
        System.out.println("local IP address: " + ip);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return ip;
}
1
2
3
4
5
6
7
8
9
10
11

自测没发现有什么问题,但是到了QA同学那里,获取到的IP地址一直是127.0.0.1......

最终,在stack overflow上找到了答案,将获取IP地址方式修改如下:

static public void localIPAddress() {
    try {
        Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
        while (enumeration.hasMoreElements()) {
            NetworkInterface network = enumeration.nextElement();
            if (network.getName().equals("en0")) {
                Enumeration<InetAddress> inner = network.getInetAddresses();
                while (inner.hasMoreElements()) {
                    InetAddress address = inner.nextElement();
                    System.out.println("local IP Address: " + address.getHostAddress()); // 根据需要获取ipv4或ipv6
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
最后更新: 3/5/2020, 11:22:58 PM