Calling methods in a Java Fx ActionEvent

jaxoncreed

I'm new to JavaFX and I want to create a view class that will call methods in a Controller when an event is triggered by a button push. My code is below:

package spacetrader.menu;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import spacetrader.Window;

public class MenuView implements Initializable {
    public Window window;
    public MenuCtrl menuCtrl;

    @FXML
    Button start;
    @FXML
    Pane background;
    @FXML
    Button exit;

    public MenuView() {};

    public MenuView(Window aWindow, MenuCtrl aMenuCtrl) {
        window = aWindow;
        menuCtrl = aMenuCtrl;
    }

    void renderMainMenu() {
        try {
            window.loadFXML(new FXMLLoader((getClass().getResource("MainMenu.fxml"))));
        } catch (IOException ex) {
            Logger.getLogger(MenuView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        start.setOnAction((ActionEvent event) -> menuCtrl.newGame());
        exit.setOnAction((ActionEvent event) -> menuCtrl.closeApplication());
    }
}

This compiles, but when I run it and press the button I get a null pointer exception on the lambda expressions. The exception refers to "menuCtrl." How should I be setting up my program to make the button call menuCtrl.newGame()?

Here's what I've tried already:

  • I've moved the setOnAction commands to between the various methods.
  • Replaced the calls to menuCtrl methods with System.out.prinln statements to confirm that this works. It does.
  • I've replaced menuCtrl methods with System.out.println(this) to ensure there isn't a scoping problem. It prints "spacetrader.menu.MenuView@74f51979" as expected.
  • Converted the Lambda expressions to anonymous inner classes
  • Used a block as the lambda's body
James_D

Your setup is unusual, in that your controller class (which you've called MenuView) is the class that calls (indirectly, via your Window class) the FXMLLoader's load method. The FXMLLoader parses the FXML, sees the fx:controller attribute, and consequently instantiates it using the default (no-argument) constructor. (I am making an assumption here that you don't call setController or setControllerFactory on the FXMLLoader in Window.loadFXML.) Thus you have two controller instances: the one which created the loader (for whom the initialize() method is never called and the @FXML-annotated fields are never injected), and one which was created by the FXMLLoader (which called the no-argument constructor, so the window and menuCtrl fields are not initialized for that instance).

You should either refactor this, so that the FXMLLoader is created and passed to the Window class for loading elsewhere (i.e. without instantiating the controller), or you should explicitly set the controller on the FXMLLoader. You can achieve the latter in two steps:

  1. Remove the fx:controller attribute from MainMenu.fxml
  2. Set the controller explicitly to the instance already created in your renderMainMenu method:

--

FXMLLoader loader = new FXMLLoader((getClass().getResource("MainMenu.fxml"))) ;
loader.setController(this);
window.loadFXML(loader);

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

XPages - Calling Java methods

From Dev

Calling the methods in java

From Dev

Calling Java Methods in XSLT

From Java

Calling multiple methods in Java

From Java

Calling the methods in a class in Java

From Dev

Calling methods on objects Java

From Java

Calling methods on string literals (Java)

From Java

Calling methods of "parent" component in Java

From Java

Calling two Java methods asynchronously

From Dev

Calling Java methods with React locally

From Java

calling java methods in javascript code

From Dev

Generics in Java preventing calling of methods

From Dev

Calling methods for my java class

From Java

Java Convert MouseEvent to ActionEvent

From Dev

Java Swing button actionEvent

From Dev

Clojure: calling a sequence of methods on a Java object

From Java

Java: Printing triangles and spaces by calling methods

From Dev

Programatically calling all methods in a Java class

From Dev

Compiler error with calling Generic methods java

From Dev

Calling methods of a Java subclass using Jython

From Java

Calling Java Methods from Shell Scripts

From Dev

calling objects from other methods in java

From Dev

Using variables for creating objects and calling methods in Java

From Dev

Calling Methods In Java - Hello World Example

From Dev

Java FXML calling methods on button clicks

From Dev

How to print a christmas tree in Java, by calling methods?

From Dev

Java swing ActionEvent for button click

From Dev

ActionEvent and MouseEvent right-click JAVA Mac

From Dev

How Variable of an Interface is Working in JAVA and Calling the Methods of Interface?