想基于Java开发一个图形界面,发现从JDK1.8开始已经支持最新的图形界面javaFx,于是创建第一个程序尝试一下。没想到第一步就有坑和难点。专门写成文章分享给大家。

创建项目

首先使用IDEA创建一个javaFX项目,点击新建项目,弹出如下窗口:

JavaFx

注意要选择JDK1.8版本,同时选择左边的JavaFx,选项。然后点击“Next”。

JavaFx

输入项目名称,点击Next,创建项目完成。

但此时如果需要Maven来管理项目,则可以选择项目,右击,然后选择“Add Framework Support…”。

JavaFx

然后公选弹出框中的Maven选项即可,项目便新增了pom.xml文件依赖。

采坑一:配置JDK

上面虽然选择了JDK版本为1.8,但未必IDEA的所有配置都是1.8,因此要在IDEA的Java compile中看一下编译是否为JDK1.8,不是需要进行修改。同时在“Project Setting”中也需要逐一检查版本的一致性。

采坑二:警告信息

此时直接启动项目,会提示如下警告信息:

objc[98716]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java (0x108e674c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x108ee14e0). One of the two will be used. Which one is undefined.

大概意思是一个类实现了两次,有其中一个被使用,不影响使用,只是提示信息。

采坑三:程序报错

执行Main类,直接抛出如下异常,直接蒙圈:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at sample.Main.start(Main.java:13)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application sample.Main

原因很简单,找不到对应的sample.fxml文件。也就是getClass().getResource(“sample.fxml”)这个方法的结果为空。因为使用了Maven,它会把java文件编译成的class文件默认放在一个名为target的文件夹中,而sample.fxml放到了Main类的上级目录,因此找不到对应的配置文件。

只需在pom.xml设置,将布局fxml文件放在target指定的位置即可。

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.fxml</include>
                <include>**/fxml/*.fxml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

再次执行程序,直接弹出一个Hello World窗口,第一个程序终于完美启动。

JavaFx


基于Idea开发第一个JavaFx程序插图4

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://www.choupangxia.com/2020/12/10/idea-javafx/