如何在 JavaFX 中初始化 DataModel

How to initialize a DataModel in JavaFX

我创建了一个基于电子邮件 class 的数据模型,它具有一个 IntegerProperty、四个 StringProperty 和一个 Date 作为参数。现在,我试图在我的 ListView 中显示发件人的 ID 和姓名,为此我在 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 ;
    this.model.loadData(null);
    **listView.setItems(model.getEmailList());**

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

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

    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());
            }
        }
    });
}

问题是我在调用此方法时得到 java.lang.NullPointerException:listView.setItems(model.getEmailList());

这是我的数据模型class:

public class DataModel {

private final ObservableList<Email> emailList = FXCollections.observableArrayList(email -> 
    new Observable[] {email.IDProperty(), email.MittenteProperty()});

private final ObjectProperty<Email> currentEmail = new SimpleObjectProperty<>(null);

public ObjectProperty<Email> currentEmailProperty() {
    return currentEmail ;
}

public final Email getCurrentEmail() {
    return currentEmailProperty().get();
}

public final void setCurrentEmail(Email email) {
    currentEmailProperty().set(email);
}

public ObservableList<Email> getEmailList() {
    return emailList ;
}

public void loadData(File file) {
    // mock...
    emailList.setAll(
            new Email(1, "Smith", "John", "Casa", "BLAAAAAAAAAAAAA", new Date(1997, 3, 2)),
            new Email(2, "Isabella", "Johnson","Bua", "BUUUUUUU", new Date(1995, 6, 2)), 
            new Email(3, "Ethan", "Williams", "Rapporto", "IIIIIIIIII", new Date(2011, 9, 8)), 
            new Email(4, "Emma", "Jones", "Chiesa", "ALEEEEEEEEEE", new Date(2000, 1, 4)), 
            new Email(5, "Pippo", "Brown", "Vignetta", "OSAAAAAAAA", new Date(1987, 4, 5))
    );
}

public void saveData(File file) { }

}

如何在不通过这种方式打开程序的情况下立即填充列表?即使我通过调用 loadData 方法填充它,我也会得到 NullPointerExcpetion。

编辑:这是主要的class:

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);
    textareaController.initModel(model);

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

EDIT2:这是 TextAreaController Class:

public class TextAreaController {

private DataModel model;
private TextArea textarea;

public void initModel(DataModel model) {
    if (this.model != null) {
        throw new IllegalStateException("Model can only be initialized once");
    }
    this.model = model ;
    model.loadData(null);//  aggiunto per far caricare i dati delle person
    model.currentEmailProperty().addListener((obs, oldEmail, newEmail) -> {
        if (oldEmail != null) {
            String id = "ID: "+Integer.toString(oldEmail.IDProperty().getValue().intValue())+"\n";
            textarea.setText(id);
            /*firstNameField.textProperty().unbindBidirectional(oldEmail.firstNameProperty());
            lastNameField.textProperty().unbindBidirectional(oldEmail.lastNameProperty());
            emailField.textProperty().unbindBidirectional(oldEmail.emailProperty());*/
        }
        if (newEmail == null) {
            textarea.setText("");
            /*firstNameField.setText("");
            lastNameField.setText("");
            emailField.setText("");*/
        } else {
            String id = "ID: "+Integer.toString(newEmail.IDProperty().getValue().intValue())+"\n";
            textarea.setText(id);
            /*firstNameField.textProperty().bindBidirectional(newEmail.firstNameProperty());
            lastNameField.textProperty().bindBidirectional(newEmail.lastNameProperty());
            emailField.textProperty().bindBidirectional(newEmail.emailProperty());*/
        }
    });
}

}

控制器:

public class Controller {
    @FXML
    private ListView<Email> listView;
    private DataModel model = new DataModel();

    @FXML
    private void initialize() {
         List<Email> emailList = model.loadData();
         listView.getItems().addAll(emailList);
    }
}

型号:

public class Email {
    int id;
    String firstProperty;
    String secondProperty;
    String thirdProperty;
    String fourthProperty;
    Date date;

    public Email(int id, String firstProperty, String secondProperty, String thirdProperty, String fourthProperty, Date date) {
         this.id = id;
         this.firstProperty = firstProperty;
         this.secondProperty = secondProperty;
         this.thirdProperty = thirdProperty;
         this.fourthProperty = fourthProperty;
         this.date = date;
    }

    @Override
    public String toString(){
        return ("ID: " + this.id + ", Name: " + this.firstProperty);
    }
}

数据模型:

public class DataModel {
    public List<Email> loadData() {

        List<Email> emailList = new ArrayList<>();

        emailList.addAll(
                Arrays.asList(
                        new Email(1, "Smith", "John", "Casa", "BLAAAAAAAAAAAAA", new Date(1997, 3, 2)),
                        new Email(2, "Isabella", "Johnson", "Bua", "BUUUUUUU", new Date(1995, 6, 2)),
                        new Email(3, "Ethan", "Williams", "Rapporto", "IIIIIIIIII", new Date(2011, 9, 8)),
                        new Email(4, "Emma", "Jones", "Chiesa", "ALEEEEEEEEEE", new Date(2000, 1, 4)),
                        new Email(5, "Pippo", "Brown", "Vignetta", "OSAAAAAAAA", new Date(1987, 4, 5))
                )
        );

        return emailList;
    }
}

希望它能奏效。