英文:
JavaFX runs in VSCode but JavaFX with Scene Builder gives "Error: JavaFX runtime components are missing, and are required to run this application"
问题
以下是要翻译的内容:
问题/目标摘要:
我希望在VSCode中使用Scene Builder制作一个JavaFX GUI。一个简单的“Hello World”程序在VSCode中正常运行。我还可以在VSCode中运行一个简单的JavaFX“Hello World”代码,没有问题。然而,使用Scene Builder的JavaFX代码给我一个错误。
这可能是问题的一部分,但“Run Code”仅适用于非JavaFX的“Hello World”。运行JavaFX(非Scene Builder)的唯一方法是通过“Run Java”。
版本:
- VSCode已更新到最新版本(v1.76)
- JavaFX是在过去一周左右下载的(v19.0.2.1)
- Scene Builder在过去一周左右安装的(可能是19.0.0)
相关扩展(无链接;帖子被标记为垃圾,试图规避):
- Java扩展包
- JavaFX支持
- 用于Java的Maven(不确定是否相关)
- 用于Java的项目管理器(不确定是否相关)
- Visual Studio Code的SceneBuilder扩展
详细信息(抱歉,这将是大量代码;想提供尽可能多的信息):
简单的Hello World:
public class testing
{
public static void main(String [] args)
{
System.out.println("HI");
}
}
此代码在“Run Code”和“Run Java”中运行,输出为“HI”。
JavaFX Hello World:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
使用“Run Code”会出现20个错误,以下是其中两个(我的问题被标记为垃圾,也许这会改变...?):
HelloWorld.java:1: error: package javafx.application does not exist
import javafx.application.Application;
^
HelloWorld.java:2: error: package javafx.event does not exist
import javafx.event.ActionEvent;
20 errors
使用“Run Java”会得到预期的输出:一个带有按钮的窗口,按钮上写着“Say 'Hello World'”,点击后会在控制台打印“Hello World!”。图片:这里
更复杂的Scene Builder
代码来自这个YouTube视频。
这是.fxml文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control>?
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>?
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="417.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainSceneController">
<children>
<Label layoutX="14.0" layoutY="14.0" prefHeight="19.0" prefWidth="392.0" text="Title" />
<TextField fx:id="tfTitle" layoutX="14.0" layoutY="33.0" prefHeight="27.0" prefWidth="392.0" />
<Button layoutX="184.0" layoutY="359.0" mnemonicParsing="false" onAction="#btnOkClicked" text="OK" />
</children>
</AnchorPane>
这是launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "testing",
"request": "launch",
"mainClass": "testing",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "TestingBasic",
"request": "launch",
"mainClass": "TestingBasic",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "App",
"request": "launch",
"mainClass": "App",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "HelloWorld",
"request": "launch",
"vmArgs": "--module-path C:/openjfx-19.0.2.1_windows-x64_bin-sdk/javafx-sdk-19.0.2.1/lib --add-modules javafx.controls,javafx.fxml",
"mainClass": "HelloWorld",
"projectName": "Java VSCode test_a97e49e3"
}
]
}
这是MainSceneController.fxml:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class MainSceneController {
@FXML
private TextField tfTitle;
@FXML
void btnOkClicked(ActionEvent event) {
Stage mainWindow = (Stage) tfTitle.getScene().getWindow();
String title = tfTitle.getText();
mainWindow.setTitle(title);
}
}
这是App.java:
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("MainScene.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
}
}
public static main(String[] args) {
System
<details>
<summary>英文:</summary>
**Summary of issue/goal:**
I wish to make a JavaFX GUI with Scene Builder in VSCode. A simple 'hello world' program runs in VSCode without issue. I can additionally run a simple 'hello world' JavaFX code in VSCode without issue. However, the JavaFX with Scene Builder code gives me an error.
This may be part of the issue, but 'Run Code' only works for non-JavaFX 'hello world'. The only way to run JavaFX (non-Scene Builder) is via 'Run Java'.
**Versions:**
- VSCode is up to date (v1.76)
- JavaFX was downloaded in past week or so (v19.0.2.1)
- Scene Builder was installed in past week or so (19.0.0 probably)
**Related Extensions (no links; post marked spam and trying to get around it):**
- Extension Pack for Java
- JavaFX Support
- Maven for Java (not sure if related)
- Project Manager for Java (not sure if related)
- SceneBuilder extension for Visual Studio Code
**In detail (sorry, this will be a lot of code; wanted to give as much information possible):**
*Simple Hello World:*
public class testing
{
public static void main(String [] args)
{
System.out.println("HI");
}
}
This code runs in 'Run Code' and 'Run Java' with output being ```HI```.
*JavaFX Hello World:*
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
/**
* @param args
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
Using 'Run Code' gives 20 errors, here are two (my question was marked spam, maybe this changes it...?):
HelloWorld.java:1: error: package javafx.application does not exist
import javafx.application.Application;
^
HelloWorld.java:2: error: package javafx.event does not exist
import javafx.event.ActionEvent;
20 errors
Using 'Run Java' gives the expected output: a window with a button saying "Say 'Hello World'" that prints "Hello World!" to the console upon click. Image: [image here](https://i.stack.imgur.com/NisSK.png)
*More complicated Scene Builder*
Code comes from [this Youtube Video](https://youtu.be/AubJaosfI-0).
Here is the .fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="417.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainSceneController">
<children>
<Label layoutX="14.0" layoutY="14.0" prefHeight="19.0" prefWidth="392.0" text="Title" />
<TextField fx:id="tfTitle" layoutX="14.0" layoutY="33.0" prefHeight="27.0" prefWidth="392.0" />
<Button layoutX="184.0" layoutY="359.0" mnemonicParsing="false" onAction="#btnOkClicked" text="OK" />
</children>
</AnchorPane>
Here is the launch.json:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "testing",
"request": "launch",
"mainClass": "testing",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "TestingBasic",
"request": "launch",
"mainClass": "TestingBasic",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "App",
"request": "launch",
"mainClass": "App",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "HelloWorld",
"request": "launch",
"vmArgs": "--module-path C:/openjfx-19.0.2.1_windows-x64_bin-sdk/javafx-sdk-19.0.2.1/lib --add-modules javafx.controls,javafx.fxml",
"mainClass": "HelloWorld",
"projectName": "Java VSCode test_a97e49e3"
}
]
}
Here is MainSceneController.fxml:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class MainSceneController {
@FXML
private TextField tfTitle;
@FXML
void btnOkClicked(ActionEvent event) {
Stage mainWindow = (Stage) tfTitle.getScene().getWindow();
String title = tfTitle.getText();
mainWindow.setTitle(title);
}
}
Here is the App.java:
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("MainScene.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
}
}
public static void main(String[] args) {
System.out.println("got here");
launch(args);
}
}
No code has errors. Running ```main``` in ```App.java``` produces
```Error: JavaFX runtime components are missing, and are required to run this application```.
('Run Java' for App.java gives same thing; 'Run Code' for App.java gives 14 errors similar to the 20 earlier about java.fx packages not existing.)
I am confused what this means.
For reference, here is the 'Configure runtime for projects' page:
[here](https://i.stack.imgur.com/WL60U.png). I have two options (17 and 19), but both fail and give me the runtime error: [here](https://i.stack.imgur.com/6qk2R.png).
----
If you could point me in the correct direction, that'd be great. I am new to StackOverflow so I appreciate the support and apologize if I've made a mistake.
</details>
# 答案1
**得分**: 1
感谢@Slaw指导我朝正确的方向前进。
**解决方案:**
这是一个愚蠢的错误。从我的起始配置出发,我只需要:
- 将所有我的文件放入一个名为src的文件夹中。
- vmArgs部分需要用于*所有*使用JavaFX的文件。
对于src文件夹:不确定为什么需要它,但移除它们会引发问题。
对于vmArgs:在```launch.json```中的形式部分```"vmArgs": "--module-path \"C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib\" --add-modules javafx.controls,javafx.fxml"```必须用于每个使用JavaFX的'type'。
例如,这是我的```launch.json```:
{
// 使用智能感知来了解可能的属性。
// 悬停以查看现有属性的描述。
// 获取更多信息,请访问:https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "testing",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "src.testing",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "testing",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "testing",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "TestingBasic",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "TestingBasic",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "App",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "App",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "HelloWorld",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "HelloWorld",
"projectName": "Java VSCode test_a97e49e3"
}
]
}
以运行其中的所有Java文件。对于我这个技能水平的人来说,要注意的是:vmArgs部分在每个*部分中都存在;每个部分都适用于您要运行的每个文件(或Java类)。
<details>
<summary>英文:</summary>
Thanks to @Slaw for pointing me in the right direction.
**Solution:**
It is a silly mistake. From my starting configuration I just had to:
- Place all my files in a folder called src.
- The vmArgs part needs to be placed for *all* the files using JavaFX
For src folder: not sure why I need it, but taking them out caused problems.
For vmArgs: the section of form ```"vmArgs": "--module-path \"C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib\" --add-modules javafx.controls,javafx.fxml",``` in ```launch.json``` must be used for each 'type' that uses JavaFX.
For example, here is my ```launch.json```:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "testing",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "src.testing",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "testing",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "testing",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "TestingBasic",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "TestingBasic",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "App",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "App",
"projectName": "Java VSCode test_a97e49e3"
},
{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "HelloWorld",
"request": "launch",
"vmArgs": "--module-path "C:/Users/Oliver/Downloads/javafx-sdk-19.0.2.1/lib" --add-modules javafx.controls,javafx.fxml",
"mainClass": "HelloWorld",
"projectName": "Java VSCode test_a97e49e3"
}
]
}
to run all the java files in there. For people of my skill level note that: the vmArgs portion is in each and every* section; each section applies to each file (or java class) you are running.
*Technically not
</details>
# 答案2
**得分**: 0
我猜在启动你的JavaFX应用程序时发生了一些问题。
1. 对于第一个问题
`Run Code` 和 `Run Java` 实际上是由不同的扩展贡献的。前者是由Code Runner提供的,而后者来自Java Debugger扩展。我建议始终使用`Run Java`,因为Code Runner无法理解你的项目的依赖关系,当你的文件使用第三方库时,你会遇到错误。
2. 对于第二个问题
你能尝试直接从启动面板启动你的项目,并确保选择了最后的配置 `HelloWorld`吗?
[![在此输入图像描述][1]][1]
[1]: https://i.stack.imgur.com/BDSJc.png
<details>
<summary>英文:</summary>
I guess something wrong happens when you launch your JavaFX application.
1. For the first question
`Run Code` and `Run Java` are contributed from different extensions actually. The former one is contributed by Code Runner while the latter one from Java Debugger extension. I recommend to always use `Run Java` because the Code runner cannot understand your project's dependencies, you will get errors when your file uses third party libraries.
2. For the second question
Can you try to launch your project directly from the launch panel and make sure the last configuration `HelloWorld` is selected?
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/BDSJc.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论