Правильно управлять моделью данных - PullRequest
0 голосов
/ 10 ноября 2018

Я пытаюсь создать почтовый ящик. Первое, что я хочу сделать, - это окно со списком электронных писем, которое позволяет пользователю видеть содержимое текстовой области в нижней части окна, просто нажав на одно из них. Ошибка, которую я получаю, является NullPointerException, когда я инициализирую DataModel в контроллере, и я не могу понять, почему:

public class MailBox extends Application {

@Override
public void start(Stage stage) throws Exception {
    BorderPane root = new BorderPane();

    FXMLLoader listLoader = new FXMLLoader(getClass().getResource("lista.fxml"));
    root.setCenter(listLoader.load());
    ListController listController = listLoader.getController();

    FXMLLoader textareaLoader = new FXMLLoader(getClass().getResource("textarea.fxml"));
    root.setBottom(textareaLoader.load());
    TextAreaController textareaController = textareaLoader.getController();

    DataModel model = new DataModel();
    listController.initModel(model); <<ERROR>>
    textareaController.initModel(model);

    Scene scene = new Scene(root, 355, 402);
    stage.setScene(scene);
    stage.show();
}

Это класс электронной почты:

public class Email {
private final IntegerProperty id = new SimpleIntegerProperty();

public final IntegerProperty IDProperty() {
    return this.id;
}

public final Integer getID() {
    return this.IDProperty().get();
}

public final void setID(final Integer id) {
    this.IDProperty().set(id);
}

private final StringProperty mittente = new SimpleStringProperty();

public final StringProperty MittenteProperty() {
    return this.mittente;
}

public final String getMittente() {
    return this.MittenteProperty().get();
}

public final void setMittente(final String mittente) {
    this.MittenteProperty().set(mittente);
}

private final StringProperty destinatario = new SimpleStringProperty();

public final StringProperty DestinatarioProperty() {
    return this.destinatario;
}

public final String getDestinatario() {
    return this.DestinatarioProperty().get();
}

public final void setDestinatario(final String destinatario) {
    this.DestinatarioProperty().set(destinatario);
}

private final StringProperty oggetto = new SimpleStringProperty();

public final StringProperty OggettoProperty() {
    return this.oggetto;
}

public final String getOggetto() {
    return this.OggettoProperty().get();
}

public final void setOggetto(final String oggetto) {
    this.OggettoProperty().set(oggetto);
}

private final StringProperty testo = new SimpleStringProperty();

public final StringProperty TestoProperty() {
    return this.testo;
}

public final String getTesto() {
    return this.TestoProperty().get();
}

public final void setTesto(final String testo) {
    this.TestoProperty().set(testo);
}

private final ObjectProperty<Date> data = new SimpleObjectProperty<Date>();

public final ObjectProperty<Date> DataProperty() {
    return this.data;
}

public final Date getData() {
    return this.data.get();
}

public final void setData(final Date data) {
    this.data.set(data);
}

public Email (int id, String mittente, String destinatario, String oggetto, String testo, Date data) {
    setID(id);
    setMittente(mittente);
    setDestinatario(destinatario);
    setOggetto(oggetto);
    setTesto(testo);
    setData(data);
}}

И это ListController, где метод, вызывающий ошибку:

public class ListController {

private ListView<Email> listView ;
private DataModel model ;

public void initModel(DataModel model) {
    // ensure model is only set once:
    if (this.model != null) {
        throw new IllegalStateException("Model can only be initialized once");
    }

    this.model = model ;
    model.loadData(null);
    listView.setItems(model.getEmailList());

    listView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> 
        model.setCurrentEmail(newSelection));

    model.currentEmailProperty().addListener((obs, oldEmail, newEmail) -> {
        if (newEmail == null) {
            listView.getSelectionModel().clearSelection();
        } else {
            listView.getSelectionModel().select(newEmail);
        }
    });

    listView.setCellFactory(lv -> new ListCell<Email>() {
        @Override
        public void updateItem(Email person, boolean empty) {
            super.updateItem(person, empty);
            if (empty) {
                setText(null);
            } else {
                setText(person.getID() + " " + person.getMittente());
            }
        }
    });
}

РЕДАКТИРОВАТЬ: @fabian это содержимое моего файла fxml:

<ListView prefHeight="200.0" prefWidth="200.0" fx:controller="mailbox.ListController" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" />

И это полная ошибка:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at mailbox.ListController.initModel(ListController.java:29)
    at mailbox.MailBox.start(MailBox.java:34)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application mailbox.MailBox

РЕДАКТИРОВАТЬ 2: FXML изменено:

<StackPane fx:controller="mailbox.ListController" xmlns:fx="http://javafx.com/fxml/1">
<ListView fx:id="listView" />

...