I am just starting out with JavaFX, and I am trying to build a simple application with a label, text field and button which, when clicked, sets the label's value to that of the text field's. Everything was going well until I connected the controller to the Main file. Here's my code:
Main.java
package application;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
private Stage primaryStage;
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage; // connect primary stage
mainWindow();
}
// main window
public void mainWindow() {
try {
// view
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/MainWindowView.fxml"));
AnchorPane pane = loader.load();
// controller
MainWindowController mainWindowController = loader.getController();
mainWindowController.setMain(this);
// scene on stage
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
MainWindowView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainWindowController">
<children>
<Label fx:id="label" alignment="CENTER" layoutX="291.0" layoutY="164.0" text="Label" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<font>
<Font size="20.0" />
</font>
</Label>
<HBox alignment="CENTER" layoutX="201.0" layoutY="208.0" spacing="20.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<children>
<TextField fx:id="field" layoutX="201.0" layoutY="208.0" />
<Button layoutX="381.0" layoutY="208.0" mnemonicParsing="false" onAction="#handleButton" text="Change Text" />
</children>
</HBox>
</children>
</AnchorPane>
MainWindowController.java
package application;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class MainWindowController {
// views
@FXML private Label label;
@FXML private TextField field;
private Main main;
// connect main class to controller
public void setMain(Main main) {
this.main = main;
}
// assign text field text to label on button click
public void handleButton() {
String text = field.getText();
label.setText(text);
field.clear();
}
}
I have tried multiple answers found on StackOverflow, but all that I have found were from 2 years ago and did not make any positive effect on my code.
EDIT: Stack trace here:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Location is not set.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at application.Main.mainWindow(Main.java:27)
at application.Main.start(Main.java:19)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application application.Main
For anyone who has this exact same problem in the future, as James_D and the other answer contributors mentioned, removing the "/" at the beginning of the path fixes the problem so use
FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindowView.fxml"));
instead of
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/MainWindowView.fxml"));
This problem can also occure even when the path is completely right.
When you create the fxml file in an Updated IDE.
Then use an older JavaFX Scene Builder to design it.
Solution :
Create the fxml file in JavaFX Scane Builder
Design the fxml file in JavaFX Scane Builder then copy this to the IDE or Project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With