0

I a trying to implement a changelistner for to a TextField in Java program, I want the field to listen for a change in values and run another method. I am trying to use

text1.textProperty().addListener(
(observable, oldvalue, newvalue) ->
    // code goes here
);

as a format wrapped inside and initialize() method. The problem I run into is when I use the initialize method i get null pointer exceptions for all of my

FXMLLoader.load(getClass().getClassLoader().getResource(".fxml"))

lines. Here is the relevant code blocks Main Class:

public class Main extends Application {

@Override
public void start(Stage primaryStage) throws Exception{
    Parent root =     FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
    primaryStage.setTitle("Pathfinder Character Builder");
    primaryStage.setScene(new Scene(root, 900, 600));
    primaryStage.show();
}

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

}

Here is the Controller Class

public class MainWindowController {

@FXML //  fx:id="myButton"
public Pane statsPane; // Value injected by FXMLLoader
public Pane skillsPane;
public Button statsButton;
public Button skillsButton;
@FXML
private TextField strStatTextBox;
public TextField dexStatTextBox;
public TextField conStatTextBox;
public TextField intStatTextBox;
public TextField wisStatTextBox;
public TextField chaStatTextBox;
public Button createStatsButton;
public Button getSetStrScore;
public BorderPane mainBorderPane;



@FXML
public void pressStatsButton(ActionEvent event) {
    statsPane.setVisible(true);
    skillsPane.setVisible(false);
}

@FXML
public void pressSkillsButton(ActionEvent event) {
    skillsPane.setVisible(true);
    statsPane.setVisible(false);
}

public void pressGetStrScoreButton(ActionEvent event) {
    updateStats();
}

public void updateStats() {
    Character char1 = Character.getInstance();
    strStatTextBox.setText(char1.getStrScore());
    dexStatTextBox.setText(char1.getDexScore());
    conStatTextBox.setText(char1.getConScore());
    intStatTextBox.setText(char1.getIntScore());
    wisStatTextBox.setText(char1.getWisScore());
    chaStatTextBox.setText(char1.getChaScore());
}

@FXML
public void pressCreateStatsButton(ActionEvent event) {
    Parent root;
    try {
        root = FXMLLoader.load(getClass().getClassLoader().getResource("rollStats.fxml"));
        Stage stage = new Stage();
        stage.setTitle("Roll My Stats");
        stage.setScene(new Scene(root, 400, 300));
        stage.showAndWait();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

The Above code Works except no change listener for strStatTextBox. If I change the code to the MainController.class to this.

public class MainWindowController {

@FXML //  fx:id="myButton"
public Pane statsPane; // Value injected by FXMLLoader
public Pane skillsPane;
public Button statsButton;
public Button skillsButton;
@FXML
private TextField strStatTextBox;
public TextField dexStatTextBox;
public TextField conStatTextBox;
public TextField intStatTextBox;
public TextField wisStatTextBox;
public TextField chaStatTextBox;
public Button createStatsButton;
public Button getSetStrScore;
public BorderPane mainBorderPane;


// Handle TextField text changes.
@FXML
private void initialize() {
    strStatTextBox.textProperty().addListener(
            (observable, oldvalue, newvalue) -> {
                System.out.println("listener works");
            }
    );
}

@FXML
public void pressStatsButton(ActionEvent event) {
    statsPane.setVisible(true);
    skillsPane.setVisible(false);
}

@FXML
public void pressSkillsButton(ActionEvent event) {
    skillsPane.setVisible(true);
    statsPane.setVisible(false);
}

public void pressGetStrScoreButton(ActionEvent event) {
    updateStats();
}

public void updateStats() {
    Character char1 = Character.getInstance();
    strStatTextBox.setText(char1.getStrScore());
    dexStatTextBox.setText(char1.getDexScore());
    conStatTextBox.setText(char1.getConScore());
    intStatTextBox.setText(char1.getIntScore());
    wisStatTextBox.setText(char1.getWisScore());
    chaStatTextBox.setText(char1.getChaScore());
}

@FXML
public void pressCreateStatsButton(ActionEvent event) {
    Parent root;
    try {
        root = FXMLLoader.load(getClass().getClassLoader().getResource("rollStats.fxml"));
        Stage stage = new Stage();
        stage.setTitle("Roll My Stats");
        stage.setScene(new Scene(root, 400, 300));
        stage.showAndWait();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

What am I doing wrong? Thanks for your help.

Here is the StackTrace

javafx.fxml.LoadException: 
/C:/Users/mlpel/Dropbox/JavaFX%20Char%20Builder/Intellij%20IDEA%20Verson/out/production/Intellij%20IDEA%20Verson/rollStats.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 **MainWindowController.pressCreateStatsButton(MainWindowController.java:83)****
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$MethodHandler.invoke(FXMLLoader.java:1769)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
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)
... 66 more
**Caused by: java.lang.NullPointerException
at MainWindowController.initialize(MainWindowController.java:47)**
... 76 more

Process finished with exit code 0

Here is the file structure FileStructure

Here are the FXML, Each have different controllers.

<Pane fx:id="statsPane" prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="rollStatsController">

<BorderPane fx:id="mainBorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainWindowController">
  • Where are the `.fxml` files located? They should be located where the `.class` files are located (not where the `.java` files are) – Idloj Jun 20 '16 at 21:08
  • 1
    Presumably (though it would help if you posted the stack trace and identified the line that threw it) `strStatTextBox` is null. Can you post the FXML file? – James_D Jun 20 '16 at 21:12
  • I am not clear on why strStatTextBox would be null. is it not referenced correctly? Not Instantiated correctly? Thanks – Michael P. Jun 20 '16 at 22:06
  • It looks like you are loading two different FXML files and trying to use the same controller class for both of the controllers. Only one of the FXML files defines an element with `fx:id="strStatTextBox"`; in the other one it is not defined so it is null (presumably; you haven't shown the FXML files, but I assume that is what is happening). – James_D Jun 20 '16 at 22:10
  • Each FXML has a unique controller file assigned in the FXML. I was having problems pasting the complete FXML in the question however so I only posted the first line with the controller defined. Part of the confusion for me is the code work fine until I attempt to add the initialize() method to create a listener. – Michael P. Jun 20 '16 at 22:45
  • Well, something is out of sync. It is clear from the stack trace that when you load `rollStats.fxml` from the `pressCreateStatsButton` that a `NullPointerException` is generated in the `initialize()` method **in `MainController`**. The only way this can happen is if the controller that is created by the FXML Loader for `rollStats.fxml` is an instance of `MainController`. Did you change the `fx:controller` attribute at some point? Perhaps the latest version of `rollStats.fxml` hasn't been deployed? – James_D Jun 20 '16 at 22:45
  • OMG: I spent 2 days trying to figure this out and for somereason (trying to figure out another issue) I set rollStatscController to Extend MainController and never undid it. once I fixed that it works perfectly.Thanks you managed to point in the right direction. – Michael P. Jun 20 '16 at 22:58
  • Well, yes, that would do it too! FWIW there's (probably? it would be rare at least) no valid reason to have one controller class as a subclass of another, but it sounds like you already figured that out. – James_D Jun 20 '16 at 23:18

0 Answers0