java – ListView没有反映更改
我在前面创建了一个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(); } } 我的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(); 为什么对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; } 你应该有 public final void setName(String name) { stepName.setValue(name); } public final String getName() { return stepName.getValue(); } public StringProperty nameProperty() { return stepName; } 并且类似地用于其他属性访问器方法. (显然,字段的名称可以是你喜欢的任何东西,因为它们是私有的.)Making the get/set methods final is good practice. 然后,create the list with an extractor.提取器是一个函数,它将列表中的每个元素映射到列表将观察到的Observables数组.如果这些值发生变化,它将向列表的观察者发送列表更新.由于ActionStep的toString()方法引用了nameProperty(),因此我假设您希望在nameProperty()更改时更新ListView.所以你想做 listOfSteps = FXCollections.observableArrayList( actionStep -> new Observable[] { actionStep.nameProperty() } // the "extractor" ); actionStepsListView.setItems(listOfSteps); 请注意,在早期版本的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); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |