Search code examples
javacontrollerjavafxfxmlscene

JavaFX transition scene from Controller


I am very new to JavaFX (and java in general) and I have been trying to transition between scenes from an FXML controller. I have tried to look up multiple solutions online however, none of them seem to work.

My main java code:

package main;

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

public class App extends Application {

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

@Override
public void start(Stage primaryStage) throws Exception {


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

    Scene scene1 = new Scene(root);

    primaryStage.setScene(scene1);
    primaryStage.setTitle("Login");
    primaryStage.show();
}

}

... and my LoginController:

package main;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class LoginController implements Initializable 
{

@FXML
private Label loginLabel;

@FXML
private TextField fieldUsername;

@FXML 
private PasswordField fieldPassword;


@FXML
public void loginEvent(ActionEvent event) throws Exception{
    //This is where I try to change the scene
    if (fieldUsername.getText().equals("admin")  && fieldPassword.getText().equals("admin")){
    Parent parent = FXMLLoader.load(getClass().getResource("Main.fxml"));
    Stage primaryStage = new Stage();
    Scene scene = new Scene (parent);
    primaryStage.setScene(scene);
    primaryStage.setTitle("Main Frame");
    primaryStage.show();
    }
    else {
        loginLabel.setText("Incorrect Username or Password");
    }
}

@Override
public void initialize(URL arg0, ResourceBundle arg1) {}

}

Here is the Error I get:

Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
... 48 more
Caused by: javafx.fxml.LoadException: 
/F:/Programming/JAVA/Eclipse/Password%204/bin/main/Main.fxml:9

at javafx.fxml.FXMLLoader.constructLoadException(Unknown Source)
at javafx.fxml.FXMLLoader.access$700(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(Unknown Source)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(Unknown Source)
at javafx.fxml.FXMLLoader$Element.processStartElement(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(Unknown Source)
at javafx.fxml.FXMLLoader.processStartElement(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at main.LoginController.loginEvent(LoginController.java:34)
... 57 more
Caused by: java.lang.ClassNotFoundException: main.MainController
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 71 more

My way of changing the scene doesn't work. How would I go about this issue? Thanks in advance.


Solution

  • What is wrong with your solution

    Your getResource argument is wrong - you should not use a file path (e.g. F:/) instead you should use something related to your class path.

    You may have other errors, I haven't checked, just wanted to note that obvious one.

    How to fix it

    Easiest solution is to place the Main.fxml in the same directory as LoginController.java and check that, when you compile the program, Main.fxml has been copied by your build system to the same directory as LoginController.class.

    For your lookup just use FXMLLoader.load(getClass().getResource("Main.fxml")); (similarly for your Login.fxml).

    Sample code

    Here is a sample for switching FXML based scenes (your code could be simpler if you want to replace the scene content as a whole rather than parts of the scene like the sample does).