angryduck
angryduck

Reputation: 31

How do you bring the package to FXMLoader in the same package?

When you have the folder structure as below,

├ Main.java
└ Bird
    ├ bird.fxml
    └ birdController

I tried three things to get "bird.fxml" from "Main", but all of them didn't work.

//Case 1
Parent root = FXMLLoader.load(getClass().getResource("bird/bird.fxml"));

//Case 2
Parent root = FXMLLoader.load(getClass().getResource("/bird/bird.fxml"));

//Case 3
Parent root = FXMLLoader.load(getClass().getResource("./bird/bird.fxml"));

Is there any other way to get FXML? If "Bird.fxml" and "BirdController" are taken out of the Bird Package, they run well.

enter image description here

Main enter image description here

enter image description here

Bird.fxml enter image description here

BirdController enter image description here

Upvotes: 0

Views: 323

Answers (1)

Abra
Abra

Reputation: 20913

First the working code and after the code, the explanations.

Class Main

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/application/Bird/Bird.fxml"));
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

File Bird.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Bird.BirdController">
  <children>
    <Label fx:id="lbGood" layoutX="236.0" layoutY="188.0" text="Good for you">
      <font>
        <Font size="20.0"/>
      </font>
    </Label>
    <Button layoutX="273.0" layoutY="237.0" mnemonicParsing="false" onAction="#onToggleButton" text="Button"/>
  </children>
</AnchorPane>

Class BirdController

package application.Bird;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class BirdController {
    @FXML
    private Label lbGood;

    @FXML
    void onToggleButton(ActionEvent event) {
        if (lbGood.getText().equals("Good for you")) {
            lbGood.setText("Bad for you");
        }
        else {
            lbGood.setText("Good for you");
        }
    }
}

Refer to the following line from the above code.

Parent root = FXMLLoader.load(getClass().getResource("/application/Bird/Bird.fxml"));

The leading forward slash in /application/Bird/Bird.fxml means that Java will search for file Bird.fxml relative to the parent directory of the base package – which is application in your code. Hence you need to write the path to the FXML file relative to that directory and remember that Java is case sensitive.

Alternatively the following will also work since the code is being executed from the application package. (Note there is no leading forward slash.)

Parent root = FXMLLoader.load(getClass().getResource("Bird/Bird.fxml"));

When I run the above code, I get the following.

screen capture

and the Label text changes when I click on the Button.

Please note that it is recommended to use java naming conventions as this will make it easier for others to read and understand your code.

Upvotes: 2

Related Questions