Ton*_*ced 3 java listview javafx observablelist javafx-8
我在前面创建了一个TableView,并为每个TableColumns注册了Properties.编辑内部数据反映在TableView中就好了.
但是,使用ListView,它是一个不同的故事.除非我关闭框架并再次打开,否则不会立即显示更改.
我的ListView包含ActionSteps.请注意,我使用了Javafx bean属性.
package application.objects;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.function.IntPredicate;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class ActionStep {
private StringProperty actionStepID;
private ObjectProperty<LocalDate> dateSet, dateFinished;
private StringProperty stepName;
private IntegerProperty completion;
private ArrayList<StepComment> comments;
public ActionStep(String name) {
actionStepID = new SimpleStringProperty();
stepName = new SimpleStringProperty();
dateSet = new SimpleObjectProperty<LocalDate>();
dateFinished = new SimpleObjectProperty<LocalDate>();
completion = new SimpleIntegerProperty();
stepName.setValue(name);
}
public void setName(String name) {
stepName.setValue(name);
}
public String getName() {
return stepName.getValue();
}
public StringProperty stepNameProperty() {
return actionStepID;
}
public void setID(String id) {
actionStepID.setValue(id);
}
public String getID() {
return actionStepID.get();
}
public StringProperty actionStepIDProperty() {
return actionStepID;
}
public void setCompletion(int percent) {
if (percent < 0 || percent > 100)
return;
completion.set(percent);
}
public int getCompletion() {
return completion.get();
}
public IntegerProperty completionProperty() {
return completion;
}
public void setDateSet(LocalDate date) {
dateSet.set(date);
}
public LocalDate getDateSet() {
return dateSet.get();
}
public ObjectProperty<LocalDate> dateSetProperty() {
return dateSet;
}
public void setDateFinished(LocalDate date) {
dateFinished.set(date);
}
public LocalDate getDateFinished() {
return dateFinished.get();
}
public ObjectProperty<LocalDate> dateFinishedProperty() {
return dateFinished;
}
public String toString() {
return stepNameProperty().get();
}
}
Run Code Online (Sandbox Code Playgroud)
我的ListView也使用ObservableList.
@FXML
private ListView<ActionStep> actionStepsListView;
private ObservableList<ActionStep> listOfSteps;
listOfSteps = FXCollections.observableArrayList();
actionStepsListView.setItems(listOfSteps);
if (plan != null) {
ArrayList<ActionStep> arrayOfSteps = plan.getStepsArrayList();
for (int i = 0; i < arrayOfSteps.size(); i++)
listOfSteps.add(arrayOfSteps.get(i));
} else
plan = new ActionPlan();
Run Code Online (Sandbox Code Playgroud)
为什么对ObservableList所做的更改不会反映在ListView中?我注意到ListView调用每个对象的toString()来在ListView中显示它们的值,而不是将它绑定到它们的Properties.
我究竟做错了什么?我应该覆盖一家细胞工厂吗?
请注意,您正在尝试使用您的单元格中的单元格执行更复杂ListView
的操作TableView
.在TableView
,细胞中显示的对象正在发生变化,因此细胞很容易观察到这一点.在ListView
,您希望单元格注意属于单元格中显示的对象的属性更改; 这是进一步的步骤,所以你必须做一些额外的编码(虽然不多,你会看到).
您可以创建一个自定义单元工厂来绑定到它stepNameProperty()
,但它很棘手(您必须确保从updateItem()
方法中的旧项取消绑定/删除侦听器).
但是,更简单的方法是使用ObservableList
定义的提取器.
首先,修复您的方法名称:您发布的代码中存在一些奇怪的不匹配.getX/setX/xProperty方法名称应该都正确匹配.即代替
public void setName(String name) {
stepName.setValue(name);
}
public String getName() {
return stepName.getValue();
}
public StringProperty stepNameProperty() {
return actionStepID;
}
Run Code Online (Sandbox Code Playgroud)
你应该有
public final void setName(String name) {
stepName.setValue(name);
}
public final String getName() {
return stepName.getValue();
}
public StringProperty nameProperty() {
return stepName;
}
Run Code Online (Sandbox Code Playgroud)
并且类似地用于其他属性访问器方法.(显然,字段的名称可以是您喜欢的任何内容,因为它们是私有的.)将get/set方法设为final是很好的做法.
然后,使用提取器创建列表.提取器是一个函数,它将列表中的每个元素映射到Observable
列表将观察到的s 数组.如果这些值发生变化,它将向列表的观察者发送列表更新.由于你ActionStep
的toString()
方法引用了nameProperty()
,我假设你想要ListView
更新如果nameProperty()
更改.所以你想做
listOfSteps = FXCollections.observableArrayList(
actionStep -> new Observable[] { actionStep.nameProperty() } // the "extractor"
);
actionStepsListView.setItems(listOfSteps);
Run Code Online (Sandbox Code Playgroud)
请注意,在早期版本的JavaFX 2.2中,ListView
没有正确观察更新事件的列表; 在Java 8发布之前不久就修复了这个问题(如果我没记错的话).(因为你标记了JavaFX8这个问题,我假设你使用的是Java 8,所以你应该没问题.)
如果您不使用Java 8,则可以使用以下(等效但更详细)的代码:
listOfSteps = FXCollections.observableArrayList(
new Callback<ActionStep, Observable[]>() {
@Override
public Observable[] call(ActionStep actionStep) {
return new Observable[] { actionStep.nameProperty() } ;
}
});
actionStepListView.setItems(listOfSteps);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3070 次 |
最近记录: |