JavaFX-TableView不会更新项目 [英] JavaFX - TableView doesn't update items

查看:92
本文介绍了JavaFX-TableView不会更新项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaFX为我的妻子编程一个词汇训练器. 每个单词都存储自己的统计值,例如她遇到该单词的频率以及提供正确答案的频率. 我已经为此设置了一个TableView,但是在培训课程之后,这些统计信息将不会更新.单词对象本身具有正确的值,但它们并未在TableView中显示. 通常,由于ObservableList的性质,TableView总是显示on对象的当前值,对吗?但是在这种情况下不是.

I'm programming a little vocabulary trainer for my wife using JavaFX. Each word stores it's own statistic values like how often she encountered the word and how often she provided a correct answer. I've set up a TableView for that, but after a training session the stats won't update. The word objects themselves have the right values but they're just not shown in the TableView. Usually the TableView always displays the current values of on object due to the nature of ObservableList, right? Not in this case though.

这是我的词汇课:

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类:

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

关于如何解决此问题的任何想法?

Any idea on how to fix this?

推荐答案

使用

Implement the mutable properties in Vocable using the JavaFX properties pattern. This allows the table cells to observe the appropriate properties and respond if they change. For values that don't change, such as german and english, you can still use regular (and final) fields. For values that change but you want to control how they change (e.g. you want an increaseGivenAnswers() method, but no general setGivenAnswers(int) method), you can use a ReadOnlyXXXWrapper and expose a ReadOnlyXXXProperty. So, e.g.:

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

}

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

For the cells to observe these properties, map the cell value factories to the properties that are defined:

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

given.setCellValueFactory(item -> item.getValue().givenAnswersProperty());
correct.setCellValueFactory(item -> item.getValue().correctAnswersProperty());
skipped.setCellValueFactory(item -> item.getValue().skippedAnswersProperty());

这篇关于JavaFX-TableView不会更新项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆