4

I have recently started working with JavaFX and I've got a kind of a problem with controller.

My problem is like this: 1) I've got fxml file in project.startup and it name is loginTab.fxml 2) Controller of this window is in project.startup.controllers and it is called LoginTabController

When I would like to set a disable property on Button (or add a listener to Toggle Group) in initialize method of my controller I've got null pointer exception. Stack trace shows that at the beggining of initialize() is null pointer.

Below I am presenting my code which caused this horrible situation. In fact I was looking for some solution but I can't find anything.

I also have checked if name is spelled propely but unfortunately it is correct.

1) First code sample is how I am loading my page:

 try{
     FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/project/startup/loginTab.fxml"));
     Parent root = fxmlLoader.load();
     Stage stage = new Stage();
     stage.initModality(Modality.APPLICATION_MODAL);
     stage.initStyle(StageStyle.DECORATED);
     stage.setTitle("System Main Menu");
     stage.setScene(new Scene(root));  
     stage.show();
 } catch(Exception ex){
     ex.printStackTrace();
 }

2) Element of my page

 <GridPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="projectgotham.startup.controllers.LoginTabController" prefHeight="200" prefWidth="500" alignment="center" hgap="20" vgap="20">
    <fx:define>
        <ToggleGroup fx:id = "typeOfLogin"/>
    </fx:define>
    <VBox spacing="5" GridPane.columnIndex="0" GridPane.rowIndex="0">
        <children>
            <Label>Choose type of login</Label>
            <RadioButton text="Face" toggleGroup="$typeOfLogin" selected = "true" userData = "Face"/>
            <RadioButton text="Fingerprint" toggleGroup="$typeOfLogin" userData = "Fingerprint"/>
            <RadioButton text="Face and Fingerprint" toggleGroup="$typeOfLogin" userData = "Face and Fingerprint"/> 
            <RadioButton text="Admin" toggleGroup="$typeOfLogin" userData = "Admin"/>
        </children>
    </VBox>
    <VBox spacing="15" GridPane.columnIndex="0" GridPane.rowIndex="1">
        <children>
            <Label>Current login progress</Label>
            <ProgressBar fx:id = "loginProgressBar" progress="0.30"/>
        </children>
    </VBox> 
    <VBox spacing="20" GridPane.columnIndex="0" GridPane.rowIndex="2">
        <children>
            <Button text="Invoke Login Action" onAction="#handleLoginAction"/>
            <Button fx:id="closeSystemBtn" text="Close System" onAction="#closeSystem"/>
        </children>
    </VBox>
    <VBox spacing="5" GridPane.columnIndex="10" GridPane.rowIndex="0">
        <children>
            <Label>Last loaded image</Label>
            <ImageView fx:id="currentImageViewer" fitHeight="150" fitWidth="200" pickOnBounds="true" preserveRatio="true" visible="true">
            </ImageView>
        </children>
    </VBox>
    <VBox spacing="15" GridPane.columnIndex="10" GridPane.rowIndex="1">
        <children>
            <Button fx:id = "testButton" text="Took a photo" onAction="#testThing"/>
            <Button text="Load a fingerprint image"/>
        </children>
    </VBox>
</GridPane>

3) My controller class

public class LoginTabController implements Initializable {

    /**
     * Initializes the controller class.
     */

    @FXML
    private ToggleGroup typeOfLogin;

    @FXML
    private Button closeSystemBtn;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        closeSystemBtn.setDisable(true);
    }   


    @FXML
    protected void handleLoginAction(ActionEvent event){

        try{
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/projectgotham/startup/LoginIdentification.fxml"));
            Parent root = fxmlLoader.load();
            Stage stage = new Stage();
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.initStyle(StageStyle.DECORATED);
            stage.setTitle("Finish login action");
            stage.setScene(new Scene(root));  
            stage.show();
        } catch(Exception ex){
            ex.printStackTrace();
            Logger.getRootLogger().error("Can't handle action connected with login : " + ex.getMessage());
        }
    }

    @FXML
    protected void closeSystem(ActionEvent event){
        Stage closeStage = (Stage) closeSystemBtn.getScene().getWindow();
        closeStage.close();
    }

    @FXML
    protected void testThing(ActionEvent event){
        typeOfLogin.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){
            @Override
            public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
                System.out.println(typeOfLogin.getSelectedToggle().getUserData().toString());
            }

        });

    }

}

I would be pleased if you could help me with this null pointer exception...

EDIT:

Stack trace:

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.access$2700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$IncludeElement.constructValue(FXMLLoader.java:1143)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at projectgotham.startup.Startup$2.handle(Startup.java:60)
at projectgotham.startup.Startup$2.handle(Startup.java:55)
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:8413)
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.NullPointerException
at projectgotham.startup.controllers.LoginTabController.initialize(LoginTabController.java:45)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 57 more
James_D
  • 201,275
  • 16
  • 291
  • 322
Thomas Clancy
  • 61
  • 1
  • 6
  • Which null pointer exception? Can you [edit] your question to include the stack trace? – James_D Sep 23 '16 at 16:53
  • And line 60 of Startup.java is `Parent root = fxmlLoader.load();`, line 45 of LoginTabController.java is `closeSystemBtn.setDisable(true);`, and the FXML you posted is `loginTab.fxml`, correct? – James_D Sep 23 '16 at 17:42
  • what if you comment or delete `closeSystemBtn.setDisable(true);` and run it again, do you still get exception? – Tomasz Mularczyk Sep 23 '16 at 17:49
  • James_D true, Tomasz Mularczyk no I don't get this exception. – Thomas Clancy Sep 23 '16 at 18:13
  • that probably means `closeSystemBtn` wasnt properly loaded and is NULL, do you get NullPointerException if you call some random method on `typeOfLogin` field? – Tomasz Mularczyk Sep 23 '16 at 18:17
  • Tomasz, for example if I will use toString() it gives me proper object identifier. I hope that is answer to Your question. – Thomas Clancy Sep 23 '16 at 18:22
  • do you have import on top of your fxml like this: `` or this ``? – Tomasz Mularczyk Sep 23 '16 at 18:27
  • The first one – Thomas Clancy Sep 23 '16 at 18:29
  • I have copied the same code into my project and it works (except I had to comment in .fxml file). Post your project structure. – Tomasz Mularczyk Sep 23 '16 at 18:45
  • Well, so what I should do? What could cause this kind of situation? :) – Thomas Clancy Sep 23 '16 at 18:48
  • Wait, are you saying that if you replace `closeSystemBtn.setDisable(true);` with `System.out.println(closeSystemBtn);` you see the expected output for a `Button` (i.e. CSS id etc) – James_D Sep 23 '16 at 18:53
  • Ok, I will try to add it to my code, James - no, I said that I could see only object identifier of this button. – Thomas Clancy Sep 23 '16 at 18:53
  • 1
    Obviously `closeSystemBtn` is null, though it should not be because the `fx:id` is correct and you have the `@FXML` annotation. I think the next thing I would try is to clean and rebuild your project (details of how depend on your IDE). This is to make sure the latest version of your FXML has been deployed to the build directory. (And, you know, make sure the FXML is saved, etc...) – James_D Sep 23 '16 at 18:58
  • James_D I have twice clean and rebuild this project and it has nothing change... :( – Thomas Clancy Sep 23 '16 at 19:03
  • @ThomasClancy can you upload your project somwhere maybe? – Tomasz Mularczyk Sep 23 '16 at 19:04
  • Well I could but I can't do that because it will be my Masters Thesis. – Thomas Clancy Sep 23 '16 at 19:05
  • Here is your project build in maven, check if there are some differences or try clone it and run it localy. https://bitbucket.org/Tomekmularczyk/todelete/src – Tomasz Mularczyk Sep 23 '16 at 19:17
  • @TomaszMularczyk thanks and I've got question to You - which version of JDK do You use? – Thomas Clancy Sep 23 '16 at 19:19
  • @ThomasClancy 1.8.0_65 – Tomasz Mularczyk Sep 23 '16 at 19:20
  • Well, the same which I use... I thought that it could be JDK case but it isn't... – Thomas Clancy Sep 23 '16 at 19:22
  • last question... does you app run normally, when you comment/delete `closeSystemBtn.setDisable(true);` ? – Tomasz Mularczyk Sep 23 '16 at 19:26
  • Yes it runs normally – Thomas Clancy Sep 23 '16 at 19:27
  • try to copy&paste this file, other than that I give up. https://bitbucket.org/Tomekmularczyk/todelete/src/386d5f75f85173de7e46e5454dedbdf7ac540fb1/src/main/resources/project/startup/loginTab.fxml?at=master&fileviewer=file-view-default – Tomasz Mularczyk Sep 23 '16 at 19:32
  • Ok I will try this solution. – Thomas Clancy Sep 23 '16 at 19:36
  • Of course, you could just do this in FXML instead of in the controller - i.e. do `` and then remove the line from the controller. However... it doesn't really fix the problem, and you really do need to fix that problem. You're not using the same controller for another FXML file, or anything crazy like that, right? – James_D Sep 23 '16 at 19:40
  • No, of course I am not using it for another FXML file :) But how I could add listener in FXML? – Thomas Clancy Sep 23 '16 at 19:46
  • Well, I have seen people do that :). So, I downloaded the project @TomaszMularczyk created in BitBucket, copied it into Eclipse, and it worked fine for me (not using Maven or anything) - no null pointer exception and the button was disabled. I am pretty convinced your FXML file is not getting deployed to the build folder. Go to the wherever your class files are being deployed (again, depends on your IDE), look for the FXML file in there, and see if it really is the same as the one in your source code. – James_D Sep 23 '16 at 19:52
  • Ok, thanks mates for Your help I will check it. – Thomas Clancy Sep 23 '16 at 19:55
  • I would like to say that project which @TomaszMularczyk put on bitbucket is also working for me - so in fact James_D maybe you're right that something is not working in NetBeans IDE... – Thomas Clancy Sep 23 '16 at 20:11
  • did you try simple restart of the IDE, or to run the same project with Eclipse for example? – Tomasz Mularczyk Sep 23 '16 at 20:23
  • restart IDE a few times... but to the Eclipse - how I could change NetBeans Project into Eclipse one? – Thomas Clancy Sep 23 '16 at 20:26
  • there are lof of example in the web http://stackoverflow.com/questions/21535023/how-to-get-your-netbeans-project-into-eclipse alternatively you can just copy those files to new project because there isnt many of them. – Tomasz Mularczyk Sep 23 '16 at 20:27
  • ok, this is another idea which I will try :) – Thomas Clancy Sep 23 '16 at 20:30
  • @Thomas Clancy are you using Eclipse? – GOXR3PLUS Sep 23 '16 at 21:53
  • No, I am using NetBeans – Thomas Clancy Sep 24 '16 at 06:12

1 Answers1

1

I add this Answer in case you are using Eclipse.With Eclipse the differences of the file that you save using SceneBuilder are not synchronized.

So every time you save the fxml file using SceneBuilder what you have to do is reopen it in a Tab.What i mean:

1)

Say for example you have 4 tabs opened in the project you are currently working.If one of those Tabs is a reference to the fxml file,then every time you save the fxml file from SceneBuilder go select another tab and then select again the Tab which is referencing to the FXML file.

or

2)

If no Tab is opened in the Project that is referencing to the FXML file then go into the project and open the FXML file to a new Tab and do the 1.

Example Image

enter image description here

Finnally

You have do to 1 or 2->1 every time you save the FXML.That's Eclipse :)

GOXR3PLUS
  • 6,877
  • 9
  • 44
  • 93