[JavaFX] NullPointer zamiast obiektu kontrollera zadeklarowanego jako @FXML

0

Witam,
W klasie AddEmployeeController mam parę buttonów (polinkowanych przez fx:id).
Teraz w klasie MainController przekazuję referencję do AddEmployeeController za pomocą

@FXML
private AddEmployeeController addEmployeeController;

i później w metodzie initialize(); chcę utworzyć uchwyt do przycisku z AddEmployeeController'a

Button addEmployeeApplyButton = addEmployeeController.getApplyButton();

niestety wyrzuca mi błąd

java.lang.NullPointerException

Gdy usuwam @FXML sprzed deklaracji kontrolera i inicjalizuje przy użyciu "new" sam button zostaje przypisany jako null...
Czy ktoś mógłby pomóc?

0

Pokaż kod kontrolerów i to przekazanie buttona. I odpowiedz na pytanie: czemu robisz to przekazanie kontrolki?

0
MrMadMatt napisał(a):

Pokaż kod kontrolerów i to przekazanie buttona. I odpowiedz na pytanie: czemu robisz to przekazanie kontrolki?

Chcę użyć buttona w MainControllerze bo muszę operować na obiekcie utworzonym właśnie w tej klasie, dlatego w funkcji initialize() chciałem zapisać całą logikę która się na tych obiektach(empOps, routOps) opiera.
Jestem bardzo początkujący i z góry przepraszam za trywialne błędy logiczne.

MainController.java

package pl.SeVeT.AppForPPAlpen;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import pl.SeVeT.AppForPPAlpen.data.Employee;
import pl.SeVeT.AppForPPAlpen.data.EmployeesOperations;
import pl.SeVeT.AppForPPAlpen.data.RoutesOperations;
import pl.SeVeT.AppForPPAlpen.fileManager.DataManager;
import pl.SeVeT.AppForPPAlpen.controllers.*;

import java.io.IOException;
import java.util.Map;

public class MainController {

    public EmployeesOperations empOps = new EmployeesOperations();
    public RoutesOperations routOps = new RoutesOperations();
    @FXML
    private VBox mainVBox;

    @FXML
    private Label welcomeLabel;

    @FXML
    private AddEmployeeController addEmployeeController = new AddEmployeeController();

    public void loadData(String routesFileName, String employeesFileName) {
        DataManager dataManager = new DataManager();
        empOps.setEmployees(dataManager.loadEmployees(employeesFileName));
        routOps.setRoutes(dataManager.loadRoutes(routesFileName));
    }

    public void buildView(Stage stage, String resourceName) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource(resourceName));
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }


    public void initialize(){

       Button addEmployeeApplyButton = addEmployeeController.getApplyButton();
        addEmployeeApplyButton.setOnAction(actionEvent -> {
            empOps.addEmployee(
                    new Employee(addEmployeeController.getNameField().getText(),
                            addEmployeeController.getLastNameField().getText(),
                            addEmployeeController.getPeselField().getText(),
                            addEmployeeController.getBirthdateField().getText(),
                            addEmployeeController.getAddressField().getText(),
                            addEmployeeController.getPhoneNumberField().getText()
                    )
            );
        });
    }
}

AddEmployeeController.java

package pl.SeVeT.AppForPPAlpen.controllers;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import pl.SeVeT.AppForPPAlpen.MainController;
import pl.SeVeT.AppForPPAlpen.data.Employee;

public class AddEmployeeController {

    @FXML
    private Button clearButton;

    @FXML
    private Button applyButton;

    @FXML
    private TextField nameField;

    @FXML
    private TextField lastNameField;

    @FXML
    private TextField peselField;

    @FXML
    private TextField birthdateField;

    @FXML
    private TextField addressField;

    @FXML
    private TextField phoneNumberField;

    public Button getClearButton() {
        return clearButton;
    }

    public Button getApplyButton() {
        return applyButton;
    }

    public TextField getNameField() {
        return nameField;
    }

    public TextField getLastNameField() {
        return lastNameField;
    }

    public TextField getPeselField() {
        return peselField;
    }

    public TextField getBirthdateField() {
        return birthdateField;
    }

    public TextField getAddressField() {
        return addressField;
    }

    public TextField getPhoneNumberField() {
        return phoneNumberField;
    }


}

0
  1. Nad metodą initialize brakuje Ci adnotacji @FXML, nie wiem czy bez niej kod z metody initialize się wgl. wykona. To raz. Dwa, gdy używasz magii FX nie jestem pewien czy referencja do AddEmployeeController nie powinna być przypisana inaczej - nie przez new tylko jakieś inne dziwne rzeczy. Nie wiem czy FX się domyśla takich rzeczy jak np. Spring.
  2. Weź ogarnij lomboka aby te gettery AddEmployeeController Ci posprząta.
  3. Do komunikacji między kontrolerami użyj szyny zdarzeń, coś jak to: https://github.com/greenrobot/EventBus bo przy większej ilości kontrolerów, zagrzebiesz się w powiązaniach referencji. Lepiej mieć pojedynczy punkt styku kontrolerów niż kilka.
  4. <autoreklama> Wydaje mi się że w przypadku JavaFX lepiej tworzyć kontrolery jawnie z podaniem FXML niż przez automagiczne mechanizmy. Tu chyba mam przykład jawnego tworzenia kontrolerów: https://github.com/matadini/translate-pdf </autorekama>

1 użytkowników online, w tym zalogowanych: 0, gości: 1