如何在JavaFX中初始化DataModel

时间:2018-11-09 12:48:44

标签: java listview javafx controller fxml

我基于Email类创建了一个数据模型,该类具有一个IntegerProperty,四个StringProperty和一个Date作为参数。现在,我试图在ListView中显示发件人的ID和名称,并为此执行我在ListController中创建以下方法:

══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 5949): The following assertion was thrown during performLayout():
I/flutter ( 5949): 'package:flutter/src/rendering/viewport.dart': Failed assertion: line 1597 pos 16:
I/flutter ( 5949): 'constraints.hasBoundedWidth': is not true.
I/flutter ( 5949): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter ( 5949): more information in this error message to help you determine and fix the underlying cause.

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

这是我的DataModel类:

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

}

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

编辑:这是主类:

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) { }

EDIT2:这是TextAreaController类:

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

}

1 个答案:

答案 0 :(得分:-2)

控制器:

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

DataModel:

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

希望它会起作用。