当 JRE6 JavaFX2.2 上的 ObservableList 更改时,JavaFX ListView 不会更新
JavaFX ListView isn't updated when ObservableList changes on JRE6 JavaFX2.2
我的问题是 ListView
(复选框列表视图)在 ObservableList
更改时没有更新。
此问题仅在我使用过时版本的 JavaFX 和过时 JRE(jre6 和 jfx2.2)时发生。当我使用 jre8 和它包含的 JavaFX 时,问题消失了,列表刷新得很好。
上述最新 JavaFX 的工作源代码:
榜单:
public ObservableList<TestCaseCheckboxModel> TestCases;
//Constructor
public SessionTestCaseModel() {
TestCases = FXCollections.observableArrayList(new Callback<TestCaseCheckboxModel, Observable[]>(){
@Override
public Observable[] call(TestCaseCheckboxModel model) {
return new Observable[]{model.TestCaseName, model.TestCaseStatus, model.TestCaseSelected};//selected might not be needed since it's bound to the listview anyways
}
});
}
列表使用的 Class 具有以下属性:
public StringProperty TestCaseName = new SimpleStringProperty();
public IntegerProperty TestCaseStatus = new SimpleIntegerProperty();
public BooleanProperty TestCaseSelected = new SimpleBooleanProperty();
列表是在外部填充的。
ListView
:
@FXML
private ListView<TestCaseCheckboxModel> testcaseListView;
//bind the checkbox select to the model property
testcaseListView.setCellFactory(CheckBoxListCell.forListView(new Callback<TestCaseCheckboxModel, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(TestCaseCheckboxModel item) {
return item.TestCaseSelected;
}
}));
//initiate the checkbox list view with the model items
testcaseListView.setItems(getModel().TestCases);
问题是当我更改列表项时,ListView 在旧的 JavaFX 版本上不会更改。
可能值得一提的是,在我 add/remove 列表中的项目之后,列表中的项目会更新(就像它们本身发生变化时应该发生的那样)。但是,据我所知,无论如何调用列表的 add
函数都会触发 ListView
更新。
另一方面,当项目属性发生变化时,这将触发新旧 JavaFX 版本,因此 Callback
提取器按预期工作:
getModel().TestCases.addListener(new ListChangeListener<TestCaseCheckboxModel>(){
@Override
public void onChanged(Change change) {
System.out.println(change);
}
});
是否有已知的解决方法?
感谢您的帮助。
在此线程的帮助下回答我自己的问题:
我实现了一个能够更新 ListView 的自定义 ListViewSkin
"from the inside":
public class UpdateableListViewSkin<T> extends ListViewSkin<T> {
public UpdateableListViewSkin(ListView<T> arg0) {
super(arg0);
}
public void refresh() {
super.flow.recreateCells();
}
}
然后我将 ObservableList
添加到 ListView
,实例化 Skin
并将其设置为 ListView
。
//initiate the checkbox list view with the model items
testcaseListView.setItems(getModel().TestCases);
UpdateableListViewSkin<TestCaseCheckboxModel> skin = new UpdateableListViewSkin<TestCaseCheckboxModel>(testcaseListView);
testcaseListView.setSkin(skin);
关键是你需要给ObservableList
添加一个有效的onChange
监听器,它会触发Skin
的.refresh()
方法。我在将 Skin
设置为 ListView
:
后立即执行此操作
getModel().TestCases.addListener(new ListChangeListener<TestCaseCheckboxModel>(){
@SuppressWarnings("unchecked")
@Override
public void onChanged(Change change) {
((UpdateableListViewSkin<TestCaseCheckboxModel>)testcaseListView.getSkin()).refresh();
}
});
此解决方法会触发 ListView
的更新功能,就像在新版本的 JavaFX 上一样。
我的问题是 ListView
(复选框列表视图)在 ObservableList
更改时没有更新。
此问题仅在我使用过时版本的 JavaFX 和过时 JRE(jre6 和 jfx2.2)时发生。当我使用 jre8 和它包含的 JavaFX 时,问题消失了,列表刷新得很好。
上述最新 JavaFX 的工作源代码:
榜单:
public ObservableList<TestCaseCheckboxModel> TestCases;
//Constructor
public SessionTestCaseModel() {
TestCases = FXCollections.observableArrayList(new Callback<TestCaseCheckboxModel, Observable[]>(){
@Override
public Observable[] call(TestCaseCheckboxModel model) {
return new Observable[]{model.TestCaseName, model.TestCaseStatus, model.TestCaseSelected};//selected might not be needed since it's bound to the listview anyways
}
});
}
列表使用的 Class 具有以下属性:
public StringProperty TestCaseName = new SimpleStringProperty();
public IntegerProperty TestCaseStatus = new SimpleIntegerProperty();
public BooleanProperty TestCaseSelected = new SimpleBooleanProperty();
列表是在外部填充的。
ListView
:
@FXML
private ListView<TestCaseCheckboxModel> testcaseListView;
//bind the checkbox select to the model property
testcaseListView.setCellFactory(CheckBoxListCell.forListView(new Callback<TestCaseCheckboxModel, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(TestCaseCheckboxModel item) {
return item.TestCaseSelected;
}
}));
//initiate the checkbox list view with the model items
testcaseListView.setItems(getModel().TestCases);
问题是当我更改列表项时,ListView 在旧的 JavaFX 版本上不会更改。
可能值得一提的是,在我 add/remove 列表中的项目之后,列表中的项目会更新(就像它们本身发生变化时应该发生的那样)。但是,据我所知,无论如何调用列表的 add
函数都会触发 ListView
更新。
另一方面,当项目属性发生变化时,这将触发新旧 JavaFX 版本,因此 Callback
提取器按预期工作:
getModel().TestCases.addListener(new ListChangeListener<TestCaseCheckboxModel>(){
@Override
public void onChanged(Change change) {
System.out.println(change);
}
});
是否有已知的解决方法?
感谢您的帮助。
在此线程的帮助下回答我自己的问题:
我实现了一个能够更新 ListView 的自定义 ListViewSkin
"from the inside":
public class UpdateableListViewSkin<T> extends ListViewSkin<T> {
public UpdateableListViewSkin(ListView<T> arg0) {
super(arg0);
}
public void refresh() {
super.flow.recreateCells();
}
}
然后我将 ObservableList
添加到 ListView
,实例化 Skin
并将其设置为 ListView
。
//initiate the checkbox list view with the model items
testcaseListView.setItems(getModel().TestCases);
UpdateableListViewSkin<TestCaseCheckboxModel> skin = new UpdateableListViewSkin<TestCaseCheckboxModel>(testcaseListView);
testcaseListView.setSkin(skin);
关键是你需要给ObservableList
添加一个有效的onChange
监听器,它会触发Skin
的.refresh()
方法。我在将 Skin
设置为 ListView
:
getModel().TestCases.addListener(new ListChangeListener<TestCaseCheckboxModel>(){
@SuppressWarnings("unchecked")
@Override
public void onChanged(Change change) {
((UpdateableListViewSkin<TestCaseCheckboxModel>)testcaseListView.getSkin()).refresh();
}
});
此解决方法会触发 ListView
的更新功能,就像在新版本的 JavaFX 上一样。