Solved - See solution at the bottom
I'm trying to load an email and password from a .xml file on the launch of a desktop application I'm working on.
The idea is, that the user can click a "remember me" checkbox first time they log in, and that will write a new .xml file containing their email and password.
Next time they open the application, their email and password should already be loaded into the Email-text field and password field.
Everything works, until the point where I'm trying to set the text of these two fields, where I get an error on launch.
If I don't try to set the text/password field and just test the variables that are populated with data from the .xml file, the outcome is as expected.
Here's my controller code:
public class LogInController{
@FXML
private VBox vbox;
private Parent fxml;
@FXML
private TextField signUpFullName, signUpEmail, signUpPassword;
@FXML
public TextField signInEmail;
@FXML
private PasswordField signInPassword;
@FXML
private Label notificationMessage, notificationMessageLogin;
@FXML
private JFXButton SignInButton, ForgotPasswordButton;
@FXML
private CheckBox rememberMeCheckbox;
private PasswordEncryptionService encryption;
private String fullName = "";
private String email = "";
private int count;
private final String xmlFilePath = "C:\\Users\\konim\\IdeaProjects\\Momentum\\src\\sample\\rememberme.xml";
private String userEmail ="";
private String password;
private String savedEmail;
private String savedPassword;
private String savedSalt;
private String savedSecuredPassword;
private boolean isEmailRegistered;
public void initialize() throws Exception {
TranslateTransition t = new TranslateTransition(Duration.seconds(0.5), vbox);
t.setToX(340);
t.play();
t.setOnFinished((e) -> {
try {
fxml = FXMLLoader.load(getClass().getResource("fxml/SignInVBox.fxml"));
vbox.getChildren().removeAll();
vbox.getChildren().setAll(fxml);
} catch (IOException e1) {
e1.printStackTrace();
}
});
File file = new File("C:\\Users\\konim\\IdeaProjects\\Momentum\\src\\sample\\rememberme.xml");
boolean exists = file.exists();
if (exists) {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
document.getDocumentElement().normalize();
savedEmail = document.getElementsByTagName("Email").item(0).getTextContent();
savedPassword = document.getElementsByTagName("Password").item(0).getTextContent();
if (savedEmail.length() >= 1 && savedPassword.length() >1) {
System.out.println(savedEmail); // TEST and value is correct
System.out.println(savedPassword); // TEST and value is correct
}
}
}
Now, If I add the following two lines inside my last if statement, I get the error that follows shortly.
signInEmail.setText(savedEmail);
signInPassword.setText(savedPassword);
Error
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:498)
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:498)
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$154(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: javafx.fxml.LoadException: /C:/Users/konim/IdeaProjects/Momentum/out/production/Momentum/sample/fxml/LogInScene.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2571)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at sample.Main.start(Main.java:14)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
... 1 more
Caused by: 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:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566)
... 17 more
Caused by: java.lang.NullPointerException
at sample.LogInController.initialize(LogInController.java:101)
... 27 more
Exception running application sample.Main
If I don't add those two lines, there's no error and everything runs smoothly.
Can you help me locate what's wrong? Tried looking up the error messages for the last two hours with no luck...
My FXML code
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox id="VBox" alignment="CENTER_LEFT" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="480.0" prefWidth="480.0" styleClass="white-pane" stylesheets="@../css/stylesheet.css" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.LogInController">
<children>
<Label text="Sign In" textFill="#f78c7b">
<font>
<Font size="20.0" />
</font>
<VBox.margin>
<Insets left="20.0" right="15.0" top="20.0" />
</VBox.margin>
</Label>
<HBox alignment="CENTER_LEFT" prefHeight="45.0" prefWidth="200.0" styleClass="tf_box">
<VBox.margin>
<Insets left="15.0" right="15.0" top="20.0" />
</VBox.margin>
<children>
<TextField fx:id="signInEmail" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" promptText="Email" styleClass="tf" HBox.hgrow="ALWAYS">
<font>
<Font size="15.0" />
</font>
</TextField>
<FontAwesomeIconView fill="#dedee4" glyphName="ENVELOPE" size="1.5em" />
</children>
</HBox>
<HBox alignment="CENTER_LEFT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" styleClass="tf_box">
<children>
<PasswordField fx:id="signInPassword" prefHeight="25.0" prefWidth="436.0" promptText="Password" styleClass="tf">
<font>
<Font size="15.0" />
</font>
</PasswordField>
<FontAwesomeIconView fill="#dedee4" glyphName="LOCK" size="1.5em" />
</children>
<VBox.margin>
<Insets left="15.0" right="15.0" top="20.0" />
</VBox.margin>
</HBox>
<HBox alignment="CENTER_RIGHT" prefHeight="45.0" prefWidth="200.0">
<VBox.margin>
<Insets left="15.0" right="15.0" top="20.0" />
</VBox.margin>
<children>
<JFXButton fx:id="ForgotPasswordButton" maxWidth="1.7976931348623157E308" onAction="#actionForgotPassword" text="Forgot Password?" textFill="#868686" HBox.hgrow="ALWAYS">
<font>
<Font size="15.0" />
</font>
<HBox.margin>
<Insets right="20.0" />
</HBox.margin>
</JFXButton>
<CheckBox fx:id="rememberMeCheckbox" mnemonicParsing="false" text="Remember me" textFill="#868686">
<HBox.margin>
<Insets right="20.0" />
</HBox.margin>
<font>
<Font size="15.0" />
</font>
</CheckBox>
<JFXButton fx:id="SignInButton" onAction="#actionSignIn" prefHeight="39.0" prefWidth="120.0" ripplerFill="WHITE" styleClass="pink-btn" text="Sign In">
<font>
<Font size="15.0" />
</font>
</JFXButton>
</children>
</HBox>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Label fx:id="notificationMessageLogin" alignment="CENTER" prefHeight="88.0" prefWidth="456.0">
<font>
<Font name="Calibri Italic" size="14.0" />
</font>
</Label>
</children>
</HBox>
</children>
</VBox>
Solution
Before I had 3 scenes - the main logIn scene and two vBox scenes that were loaded into the main LogIn scene on initialize or changed after a transition.
I used this code inside a transition:
fxml = FXMLLoader.load(getClass().getResource("fxml/SignInVBox.fxml"));
vbox.getChildren().removeAll();
vbox.getChildren().setAll(fxml);
Now, instead of having three different scenes I just added them all together and used .setVisible(true/false) on the two vBox's when my action-triggers were triggered.
I don't know exactly why the problem was caused, but at least it's fixed now. Guess it has something to do with the way I called a new scene, as they all use the same controller, which in my head would mean it tries to call the controller from within the controller, kind of recursive'ish?
If anyone can clarify whether my theory is right, I'd love to learn.
Thanks.