1

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.

  • I guess signInEmail is not initialized. Please double check the class package fx:controller="sample.LogInController". – Oleks Feb 25 '19 at 17:02
  • I had left out some code that I didn't think was needed, but I've updated the above code to include that. It's only some load/transition of a .fxml file. I haven't build anything yet. Just running the code in IntelliJ? If that's what you mean :-) Only a few months into programming so there are still a lot of foreign words for me to learn. Kleopatra, thanks for helping me improve! – Kim André Langholz Feb 25 '19 at 17:32
  • I tried it and it works for me. Well, i had to add two additional action handlers( from the ST I figure you have them in place) and also changed the jfxbuttons into normal button as well as removed the fontawesome(as I dont have it at hand). But with that the dialog came up and I was able to set the respective fields. So I am inclined to think that there is something with the fxml - I think it pulls the wrong thing. I am pretty sure it is not in the controller code you posted. – kai Feb 25 '19 at 17:54
  • Hmm. That just annoys me even more :-) I'll try going over the fxml code once again. – Kim André Langholz Feb 25 '19 at 18:17
  • no - i dont think its the file you posted. I thinkt it loads a outdated one. Try to clean and rebuild and make sure that in your target(ymmv) structure the correct file is inplace(no duplicates, no old file...) -> "/C:/Users/konim/IdeaProjects/Momentum/out/production/Momentum/sample/fxml/LogInScene.fxml" – kai Feb 25 '19 at 18:20
  • what package has the java class LogInController? – Oleks Feb 25 '19 at 18:25
  • I am not sure that the approach '@FXML private Foo foo1, foo2, foo3, foo4;' will work properly. Pls try to edit the code '@FXML private Foo foo1;@FXML private Foo foo2;@FXML private Foo foo3; @FXML private Foo foo4;' – Oleks Feb 25 '19 at 19:01
  • You could also try to set controller manually and check if fields are null FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("test.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); – Oleks Feb 25 '19 at 19:56
  • Nothing has worked so far... Also, none of my TextField.getText() or TextField.setText() are working now. At least they were working before, but now it errors out on every single one of them :S – Kim André Langholz Feb 25 '19 at 21:39
  • Your error message says `LogInScene.fxml` loading is the problem. Yet, I don't see any code or FXML related to `LogInScene.fxml`. I am guessing maybe `LogInScene` in your FXML Controller attribute should be named `LogInController`? – SedJ601 Feb 26 '19 at 00:40
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Zephyr Feb 26 '19 at 03:16
  • Just rechecked and LogInScene.fxml is also using the LogInController, so that's unfortunately not the issue :( Zephyr, I'll try to read and understand that. – Kim André Langholz Feb 26 '19 at 07:23
  • Problem solved! Thank you all for your time. I've updated my post with my solution. – Kim André Langholz Feb 26 '19 at 07:39
  • 4
    sry to spoil your day .. but that's not a solution, it's merely masking the problem ;) Which seems to be that for some reason those two fields are not injected - you _must_ find that reason. On to a debugging round, either top-down: strip away parts until the problem disappears or bottom-up: start with a working minimal example and add parts until the problem appears. Happy hunting :) – kleopatra Feb 26 '19 at 09:05
  • Got to be kidding me... :-( Thanks for letter me know. Guess that's the only way I'm going to improve. – Kim André Langholz Feb 26 '19 at 17:11
  • I got it, at least I strongly believe so. Before I had 3 scenes. 2 of which were minor vBox's that were loaded into the main scene when a transition had happened. I don't know if the problem occurs when I load a new scene onto another scene when they both use the same controller, but now I combined everything into 1 scene and now I don't have any problems at all. Still able to make transitions work and all my textfields/passwordfields are responding without the need of a = new TextField(); – Kim André Langholz Feb 26 '19 at 18:10
  • Please do not post answers in the question. Answers should be posted separately, as answers. – Cody Gray - on strike Feb 26 '19 at 18:13

0 Answers0