0

I have a program that was created with java swing, but I hit a point where using it without much online help with issues I ran into so I am starting to learn JavaFX and using fxml for the gui, so I tried to create the main window in JavaFX code. With only code, I was able to make it appear how I wanted. I then decided to switch it to fxml, so I created the fxml file, added the code in my java file to load it, but when i ran the program, I keep getting the error "Caused by: java.lang.ClassNotFoundException: javafx.scene.control.VBox", or the same for HBox, depending on which I used. I tried figuring it out myself, also tried chatGpt, but but I couldn't find a solution. What confuses me is that when I first created the JavaFX project in VS Code, it used VBox in the fxml, but worked fine. I have copied all code that that used, just changed the fxml nodes. For context, here is the module file, my code, and the fxml file.

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>

Also, here is the directory setup src |-- main |-- java | |-- gearworks | |-- App.java | |-- resources |-- gearworks |-- BasicGui.fxml

This is just the simple version of the program I am trying to make, I just kept shrinking the design, hoping that at some point it would work and I would go from there, but it never did.

This was the original code that worked before trying to use fxml, minus the imports

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();
    }
}

I started with a large gui design with more code, which didn't work, so what I tried was to make the code as small as possible, ending up the simple program said before. I expected that at some point, I would take a line of code that it didn't like, and then systematically adding it back until I found the issue.

0

1 Answer 1

5

The JavaFX layout classes, such as HBox, VBox, and BorderPane, etc., are in the javafx.scene.layout package (not the javafx.scene.control package).

Hence when the FXMLLoader encounters javafx.scene.control.HBox it throws a ClassNotFoundException, because there is no such class.

Replace

<?import javafx.scene.control.HBox ?>

with

<?import javafx.scene.layout.HBox ?>

in the FXML file.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.