Reputation: 61
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
Upvotes: 4
Views: 3204
Reputation: 7265
I add this Answer in case you are using
Eclipse
.WithEclipse
the differences of the file that you save usingSceneBuilder
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
Finnally
You have do to 1 or 2->1 every time you save the FXML.That's Eclipse :)
Upvotes: 1