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
Location is not set.
This exception states that your FXML file is unreachable by the code. If you have your fxml file inside any package then specify it with the package name.
i've had the same problem with the CORRECT PATH i was working in scene builder 8.5 i upgraded it to 11.0 and now its working (i've redesigned all the GUI).
guess its this ?
I also met this case, you please follow me hope to succeed: Tool> Options> Java> JavaFX> Scenne Buider Home> Change Link. Your route to Scenne Buider is unsuitable, it took me hours to find, it is time consuming but it will be a matter of always important when starting JavaFX.
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.
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
instead of