我正在为使用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()));
}
}
有关如何解决这个问题的想法吗?
答案 0 :(得分:1)
使用JavaFX properties pattern在Vocable
中实现可变属性。这允许表格单元格观察适当的属性并在它们发生变化时作出响应。对于不会更改的值,例如german
和english
,您仍然可以使用常规(和最终)字段。对于更改但您想要控制其更改方式的值(例如,您需要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);
}
}