提问人:Jacob Williams 提问时间:11/18/2023 更新时间:11/18/2023 访问量:42
为什么我的 JavaFX 程序使用 fxml 收到错误“Caused by: java.lang.ClassNotFoundException: javafx.scene.control.VBox”?
Why is my JavaFX program using fxml getting the error "Caused by: java.lang.ClassNotFoundException: javafx.scene.control.VBox"?
问:
我有一个用 java swing 创建的程序,但我遇到了一个问题,在没有太多在线帮助的情况下使用它,所以我开始学习 JavaFX 并使用 fxml 作为 gui,所以我尝试在 JavaFX 代码中创建主窗口。仅使用代码,我就能够让它看起来像我想要的样子。然后我决定将其切换到fxml,因此我创建了fxml文件,在我的java文件中添加了代码以加载它,但是当我运行该程序时,我不断收到错误“Caused by: java.lang.ClassNotFoundException: javafx.scene.control.VBox”,或者HBox也是如此,具体取决于我使用的。我试着自己弄清楚,也尝试过chatGpt,但我找不到解决方案。让我感到困惑的是,当我第一次在 VS Code 中创建 JavaFX 项目时,它在 fxml 中使用了 VBox,但工作正常。我已经复制了使用的所有代码,只是更改了fxml节点。 对于上下文,这里是模块文件、我的代码和 fxml 文件。
module gearworks {
requires javafx.controls;
requires javafx.fxml;
opens gearworks to javafx.fxml;
exports gearworks;
}
package gearworks;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
/**
* JavaFX App
*/
public class App extends Application {
private BorderPane root;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/gearworks/BaseGui.fxml"));
try {
root = loader.load();
System.out.println((root == null) + " root is null");
if (root == null) {
throw new IOException("FXML root is null");
}
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(root, 1300, 600);
primaryStage.setScene(scene);
primaryStage.setTitle("Test Gui");
primaryStage.setOnCloseRequest(e -> primaryStage.close());
primaryStage.show();
}
}
<?fxml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.171"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="gearworks.App">
<top>
<HBox>
<Children>
<Button text="button 1" />
<Label text="label 1" />
<Button text="button 2" />
</Children>
</HBox>
</top>
</BorderPane>
另外,这里是目录设置 来源 |-- 主 |-- 爪哇 | |-- 齿轮厂 | |-- App.java | |-- 资源 |-- 齿轮厂 |-- BasicGui.fxml
这只是我试图制作的程序的简单版本,我只是不断缩小设计,希望在某个时候它会起作用,我会从那里开始,但它从未这样做过。
这是在尝试使用 fxml 之前工作的原始代码,减去导入
public class App extends Application {
private BorderPane root;
private HBox openFilePanel, saveFilePanel, dataManipulationPanel, jobSelectionPanel, displayPanel, bottomPanel,
jobFilterPanel;
private VBox bottom;
private Label openFilePathLabel, saveFilePathLabel, currentJob;
private Button chooseOpenFile, updateBidders, chooseSaveFolder, saveExcel, filterJobs, addPricing, previousJob,
nextJob;
private final Font TITLE_FONT = Font.font("Monospaced", FontWeight.BOLD, 50);
private final Font FONT = Font.font("Monospaced", FontWeight.NORMAL, 16);
private final String css = this.getClass().getResource("Element_Styles.css").toExternalForm();
// Dark Theme Colors
private final Color PRIMARY_FONT_COLOR = Color.rgb(0, 179, 189);
private final Color SECONDARY_FONT_COLOR = Color.rgb(55, 136, 186);
private final Color TERTIARY_FONT_COLOR = Color.rgb(192, 155, 82);
private final Color QUATERNARY_FONT_COLOR = Color.rgb(61, 86, 123);
private final Color PRIMARY_BACKGROUND = Color.rgb(13, 21, 33);
private final Color SECONDARY_BACKGROUND = Color.rgb(16, 26, 41);
private final Color TITLE_FONT_COLOR = TERTIARY_FONT_COLOR;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
root = new BorderPane();
openFilePanel = new HBox();
openFilePanel.setPadding(new Insets(10));
openFilePanel.setAlignment(Pos.CENTER_LEFT);
openFilePathLabel = new Label("File Path: ");
openFilePathLabel.setPadding(new Insets(10));
openFilePathLabel.setFont(FONT);
openFilePathLabel.setTextFill(QUATERNARY_FONT_COLOR);
chooseOpenFile = new Button("Open Bidding File...");
updateBidders = new Button("Add Update Bidders");
updateBidders.setDisable(true);
// Add spacer to push the label to the left
Region ofpSpacer = new Region();
HBox.setHgrow(ofpSpacer, Priority.ALWAYS);
openFilePanel.getChildren().addAll(chooseOpenFile, openFilePathLabel, ofpSpacer, updateBidders);
saveFilePanel = new HBox();
saveFilePanel.setPadding(new Insets(10));
saveFilePanel.setAlignment(Pos.CENTER_LEFT);
saveFilePathLabel = new Label("Directory Path: ");
saveFilePathLabel.setPadding(new Insets(10));
saveFilePathLabel.setFont(FONT);
saveFilePathLabel.setTextFill(QUATERNARY_FONT_COLOR);
chooseSaveFolder = new Button("Choose a Save Folder...");
saveExcel = new Button("Export Excel File");
// Add spacer to push the label to the left
Region sfpSpacer = new Region();
HBox.setHgrow(sfpSpacer, Priority.ALWAYS);
saveFilePanel.getChildren().addAll(chooseSaveFolder, saveFilePathLabel, sfpSpacer, saveExcel);
dataManipulationPanel = new HBox();
dataManipulationPanel.setPadding(new Insets(10, 10, 0, 10));
filterJobs = new Button("Confirm Selected Jobs");
addPricing = new Button("Add Pricing to Jobs");
jobFilterPanel = new HBox();
jobFilterPanel.setSpacing(10);
jobFilterPanel.getChildren().addAll(filterJobs, addPricing);
previousJob = new Button("<< Previous Job");
currentJob = new Label("(00/00)");
currentJob.setFont(FONT);
currentJob.setTextFill(QUATERNARY_FONT_COLOR);
nextJob = new Button("Next Job >>");
jobSelectionPanel = new HBox();
jobSelectionPanel.setSpacing(10);
jobSelectionPanel.setAlignment(Pos.CENTER);
HBox.setHgrow(jobSelectionPanel, Priority.ALWAYS); // Expand to fill available space
jobSelectionPanel.getChildren().addAll(previousJob, currentJob, nextJob);
dataManipulationPanel.getChildren().addAll(jobFilterPanel, jobSelectionPanel);
bottom = new VBox();
bottom.getChildren().addAll(dataManipulationPanel, saveFilePanel);
primaryStage.setTitle("Test Gui");
root.setTop(openFilePanel);
Label titleLabel = new Label("BIDDING PROGRAM");
titleLabel.setFont(TITLE_FONT);
titleLabel.setTextFill(TITLE_FONT_COLOR);
Label descriptionLabel = new Label("Click \"Open Bidding File\" To Get Started");
descriptionLabel.setFont(FONT);
descriptionLabel.setTextFill(SECONDARY_FONT_COLOR);
VBox displayBox = new VBox(titleLabel, descriptionLabel);
displayBox.setAlignment(Pos.CENTER);
displayBox.setSpacing(10);
displayBox.setBackground(new Background(new BackgroundFill(SECONDARY_BACKGROUND, null, null)));
root.setCenter(displayBox);
root.setBottom(bottom);
Scene scene = new Scene(root, 1300, 600);
primaryStage.setScene(scene);
scene.getStylesheets().add(css);
primaryStage.setOnCloseRequest(e -> primaryStage.close());
primaryStage.show();
}
}
我从一个包含更多代码的大型 gui 设计开始,但没有奏效,所以我尝试的是使代码尽可能小,最终得到了之前所说的简单程序。我预计在某个时候,我会占用一行它不喜欢的代码,然后系统地将其添加回去,直到我发现问题所在。
答:
JavaFX 布局类(如 、 和 等)位于包中(而不是包中)。HBox
VBox
BorderPane
javafx.scene.layout
javafx.scene.control
因此,当遇到时,它会抛出一个 ,因为没有这样的类。FXMLLoader
javafx.scene.control.HBox
ClassNotFoundException
取代
<?import javafx.scene.control.HBox ?>
跟
<?import javafx.scene.layout.HBox ?>
在 FXML 文件中。
评论