watchmerisxe watchmerisxe -4 years ago 256
Java Question

JavaFX nullpointer exception when using new nodes

I added a hamburger, a drawer and a text. All of the only work when I initialize them with for example Text text = new Text(); or JFXDrawer drawer = drawer. When I just write private Text text or porivate JFXdrawer drawer I get a nullpoint exception. Can someone please tell me what I am doing wrong here... thank you so much.

Main:

import com.jfoenix.controls.JFXTextField;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.awt.event.ActionEvent;

public class Main extends Application {

@Override
public void start(Stage primaryStage) throws Exception{

Parent root = FXMLLoader.load(getClass().getResource("StartWindow.fxml"));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}

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

}
}

Answer Source

Issue and Solution

Don't write:

@FXML 
JFXDrawer drawer = new JFXDrawer();

Instead just write:

@FXML 
JFXDrawer drawer;

And in your FXML have a corresponding fx:id defined:

<JFXDrawer fx:id="drawer" .../>

Note: your sample code already has the fx:id defined, so all you need to do is delete the = new JFXDrawer() for the code to work.

Testing and explanation

As far as the drawer and hamburger go, I loaded up your code, deleted the new references for FXML variables and ran the code and it seemed to work fine to me (no null pointer).

I really can't help fix all of the problems in the project.

By deleted the new references, I mean that I deleted: = new JFXDrawer(). It is unnecessary and wrong because JFXDrawer is already created and injected by the FXMLLoader. If you set it to a new value, the injected value would be lost and you would lose the connection between your reference and the FXML documentation.

Further explanation can be found in James_D's answer on FXML declarations.

Other Potential Issues

These are not related to the issue in your question, just some things I noted on review:

  1. Use Platform.exit(), not System.exit(0).
  2. Switching on an accessibility String in response to mouse clicks on buttons to perform actions is weird. Don't do it. The accessibility Strings should be reserved for accessibility related operations. Instead you should use the action handler for the button. As the buttons are defined in FXML, you should be able to just define an onAction="#handleXXX" handler where XXX is just the name of the action to perform and will vary from button to button and the handler is defined in your Controller.
  3. Just naming the Controller controller isn't right. Presumably you have lots of controllers and need different names to distinguish them. You should not try to share a single controller between FXML documents (I don't know that you are trying to do that, but just some general advice).
  4. Adding to the anchor pane child list on FXML loads seems wrong too. If you keep adding new panes to an existing anchor pane, the older panes that you added will remain in the anchor pane (just layered underneath the new panes). That is unlikely to be what you want. I don't know quite what you want, so I can't advise you on what you should do instead (perhaps a anchorPane.getChildren().setAll(newPane) to completely replace the current contents of the anchorPane, but perhaps something different).
  5. Additionally, just setting children into AnchorPane without also setting anchor constraints (topAnchor, leftAnchor, etc.) is unusual, because without constraints an AnchorPane doesn't add much value and you could just use a standard Pane or StackPane instead.
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download