JavaFX - TableView不会更新项目

时间:2017-03-02 13:42:17

标签: java javafx tableview observable

我正在为使用JavaFX的妻子编写一个小词汇训练师。 每个单词都存储着自己的统计值,例如她遇到单词的频率以及她提供正确答案的频率。 我为此设置了一个TableView,但在训练后,统计数据不会更新。单词对象本身具有正确的值,但它们不会在TableView中显示。 由于ObservableList的性质,TableView通常会始终显示on对象的当前值,对吧?但不是在这种情况下。

这是我的词类:

public class Vocable
{
    private String german;
    private String english;
    private int givenAnswers, correctAnswers, skippedAnswers;

    public Vocable(String ger, String eng)
    {
        german = ger;
        english = eng;
        givenAnswers = 0;
        correctAnswers = 0;
        skippedAnswers = 0;
    }

    public String getGerman()
    {
        return german;
    }

    public String getEnglish()
    {
        return english;
    }

    public int getGivenAnswers() 
    {
        return givenAnswers;
    }

    public void increaseGivenAnswers() 
    {
        this.givenAnswers++;;
    }

    public int getCorrectAnswers() 
    {
        return correctAnswers;
    }

    public void increaseCorrectAnswers() 
    {
        this.correctAnswers++;
    }

    public int getSkippedAnswers() 
    { 
        return skippedAnswers;
    }

    public void increaseSkippedAnswers() 
    {
        this.skippedAnswers++;
    }
}

这是我的View-class:

public class OverviewView extends VBox
{
    private OverviewPresenter presenter;

    private TableView<Vocable> overviewTable;
    private TableColumn<Vocable, String> german;
    private TableColumn<Vocable, String> english;
    private TableColumn<Vocable, Number> given;
    private TableColumn<Vocable, Number> correct;
    private TableColumn<Vocable, Number> skipped;

    private Button delete, back, showStats, add;

    public OverviewView()
    {
        initView();
    }

    private void initView()
    {
        BorderPane pane = new BorderPane();

        overviewTable = new TableView<>();
        german = new TableColumn<>("German");
        english = new TableColumn<>("English");
        given = new TableColumn<>("given");
        correct = new TableColumn<>("correct");
        skipped = new TableColumn<>("skipped");

        german.setResizable(true);
        english.setResizable(true);
        given.setResizable(true);
        correct.setResizable(true);
        skipped.setResizable(true);

        delete = new Button("Delete");
        delete.setOnAction(e ->     presenter.deleteVocable(overviewTable.getSelectionModel().getSelectedItem()));

        back = new Button("Back");
        back.setOnAction(e -> presenter.showMainView());

        showStats = new Button("Statistics");
        showStats.setOnAction(e -> presenter.showStatistics());

        add = new Button("Add Vocbale");
        add.setOnAction(e -> presenter.showAddDialog());

        overviewTable.getColumns().add(german);
        overviewTable.getColumns().add(english);
        overviewTable.getColumns().add(given);
        overviewTable.getColumns().add(correct);
        overviewTable.getColumns().add(skipped);

        german.prefWidthProperty().bind(overviewTable.widthProperty().multiply(0.35));
        english.prefWidthProperty().bind(overviewTable.widthProperty().multiply(0.35));
        given.prefWidthProperty().bind(overviewTable.widthProperty().multiply(0.10));
        correct.prefWidthProperty().bind(overviewTable.widthProperty().multiply(0.10));
        skipped.prefWidthProperty().bind(overviewTable.widthProperty().multiply(0.10));

        pane.setCenter(overviewTable);

        HBox box = new HBox(50);
        box.getChildren().addAll(back, delete, add, showStats);

        pane.setBottom(box);
        BorderPane.setMargin(box, Constants.DEFAULT_BP_MARGINS);

        pane.setPadding(Constants.DEFAULT_PADDING);

        getChildren().add(pane);
    }

    public void setTableContent(ObservableList<Vocable> list)
    {
        overviewTable.setItems(list);

        german.setCellValueFactory(item -> new     SimpleStringProperty(item.getValue().getGerman()));
    english.setCellValueFactory(item -> new     SimpleStringProperty(item.getValue().getEnglish()));

        given.setCellValueFactory(item -> new     SimpleIntegerProperty(item.getValue().getGivenAnswers()));
        correct.setCellValueFactory(item -> new     SimpleIntegerProperty(item.getValue().getCorrectAnswers()));
    skipped.setCellValueFactory(item -> new     SimpleIntegerProperty(item.getValue().getSkippedAnswers()));
    }
}

有关如何解决这个问题的想法吗?

1 个答案:

答案 0 :(得分:1)

使用JavaFX properties patternVocable中实现可变属性。这允许表格单元格观察适当的属性并在它们发生变化时作出响应。对于不会更改的值,例如germanenglish,您仍然可以使用常规(和最终)字段。对于更改但您想要控制其更改方式的值(例如,您需要increaseGivenAnswers()方法,但不需要常规setGivenAnswers(int)方法),您可以使用ReadOnlyXXXWrapper并公开{{1 }}。所以,例如:

ReadOnlyXXXProperty

要让单元格观察这些属性,请将单元格值工厂映射到定义的属性:

public class Vocable
{

    private final String german;
    private final String english;
    private final ReadOnlyIntegerWrapper givenAnswers = new ReadOnlyIntegerWrapper();
    private final ReadOnlyIntegerWrapper correctAnswers = new ReadOnlyIntegerWrapper();
    private final ReadOnlyIntegerWrapper skippedAnswers = new ReadOnlyIntegerWrapper();


    public Vocable(String ger, String eng)
    {
        german = ger;
        english = eng;
        givenAnswers.set(0);
        correctAnswers.set(0);
        skippedAnswers.set(0);
    }

    public String getGerman()
    {
        return german;
    }

    public String getEnglish()
    {
        return english;
    }

    public ReadOnlyIntegerProperty givenAnswersProperty() {
        return givenAnswers.getReadOnlyProperty() ;
    }

    public final int getGivenAnswers() 
    {
        return givenAnswersProperty().get();
    }

    public void increaseGivenAnswers() 
    {
        givenAnswers.set(getGivenAnswers()+1);
    }


    public ReadOnlyIntegerProperty correctAnswersProperty() {
        return correctAnswers.getReadOnlyProperty();
    }

    public final int getCorrectAnswers() 
    {
        return correctAnswersProperty().get();
    }

    public void increaseCorrectAnswers() 
    {
        this.correctAnswers.set(getCorrectAnswers()+1);
    }

    public ReadOnlyIntegerProperty skippedAnswersProperty() {
        return skippedAnswers.getReadOnlyProperty();
    }

    public final int getSkippedAnswers() 
    {
        return skippedAnswersProperty().get();
    }

    public void increaseSkippedAnswers() 
    {
        this.skippedAnswers.set(getSkippedAnswers()+1);
    }

}