文章目录
1. 引言
学习一门新语言最好的方式进行项目开发实战,例如我们可以自己做一些小工具应用于工作或学习,提供效率,这样有利于保持学习兴趣和进一步巩固开发知识。我在学习java的过程中,一直想使用它做些小工具。
JavaFX 是一个开源的下一代客户端应用平台,适用于基于Java构建的桌面、移动端和嵌入式系统, 使用它可以快速开发客户端应用。下面我参考官网教程,使用IDEA基于Gradle搭建Javafx的开发环境。
2. 官方资料
1.官网地址
3. 开发包准备
3.1 新建JavaFx demo Gradle工程
- 新建工程
- 创建包org.yangyongfeg, 并添加一个空类MainApp.class,工程结构如下:
3.2下载JDK
目前Javafx比较新的版本为Javafx11,其要求的最低版本:JDK 11,因此们需要使用IDEA下载JDK11。
3.3 配置工程使用的JDK
因为电脑上还安装JDK8,IDEA默认使用JDK8, 因此需要修改工程配置,使其使用JDK11。
- 配置gradle的JVM
2.配置工程的JVM
点击 “FILE” --> “Project structure” -->“SDKs”
- 配置系统Java JVM版本
配置环境变量JAVA_HOME设置为与gradle同样的JVM.
4. 修改build.gradle
参考官网版本,我们将javafx版本配置为11.0.2,设置主类为org.yangyongfeng.MainApp,然后同步工程,获得javafx依赖。
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
group 'org.openjfx'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
test {
useJUnitPlatform()
}
javafx {
version = "11.0.2"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
mainClassName = 'org.yangyongfeng.MainApp'
工程同步成功后,在External libraries中可以看到javafx依赖。
5. 添加源码
添加MainApp., FXMLController.java, scene.fxml文件。
5.1 MainApp.java
package org.yangyongfeng;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.net.URL;
import static javafx.fxml.FXMLLoader.*;
public class MainApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/scene.fxml"));
stage.setTitle("Hello World");
stage.setScene(new Scene(root, 300, 275));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
5.2 FXMLController.java
package org.yangyongfeng;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
public class FXMLController implements Initializable {
@FXML
private Label label;
@Override
public void initialize(URL url, ResourceBundle rb) {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
// label.setText("Hello, JavaFX " + javafxVersion + "\nRunning on Java " + javaVersion + ".");
}
}
5.2 scene.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.yangyongfeng.FXMLController"
prefHeight="400.0" prefWidth="600.0">
</AnchorPane>
6. 运行工程
- 点击 HelloFx -> Tasks -> build -> build 编译工程
- 点击 HelloFx -> Tasks -> application -> run 运行工程
- 运行结果
7. 常见错误
错误1
Exception in thread "WindowsNativeRunloopThread" java.lang.NoSuchMethodError: <init>
at javafx.graphics/com.sun.glass.ui.win.WinApplication.staticScreen_getScreens(Native Method)
at javafx.graphics/com.sun.glass.ui.Screen.initScreens(Screen.java:412)
at javafx.graphics/com.sun.glass.ui.Application.lambda$run$1(Application.java:152)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:829)
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.graphics/com.sun.prism.d3d.D3DPipeline.getAdapterOrdinal(D3DPipeline.java:205)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.assignScreensAdapters(QuantumToolkit.java:695)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runToolkit(QuantumToolkit.java:313)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$startup$10(QuantumToolkit.java:258)
at javafx.graphics/com.sun.glass.ui.Application.lambda$run$1(Application.java:153)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:829)
原因:编译Javafx的JDK版本比实际运行JDK版本要高(环境编量设定的JVM版本),将两者设置成一致即可。
错误2
错误描述:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
at org.yangyongfeng.MainApp.start(MainApp.java:18)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
... 1 more
Exception running application org.yangyongfeng.MainApp
Caused by: java.lang.RuntimeException: Exception in Application start method
Caused by: java.lang.NullPointerException: Location is required.
错误原因:
Parent root = FXMLLoader.load(getClass().getResource("scene.fxml"));
加载scene.fxml资源文件失败,造成NullPointerException异常,在资源文件名前加上"/"即可。
Parent root = FXMLLoader.load(getClass().getResource("/scene.fxml"));
8. 完整工程代码
git仓库 https://gitee.com/yyf_sea/hello-fx.git
9. 关注我
关注我的公众号,分享更多嵌入式,java开发原创文章。
‘’