Java ListView未反映更改

Java ListView未反映更改,java,listview,javafx,javafx-8,observablelist,Java,Listview,Javafx,Javafx 8,Observablelist,不久前,我创建了一个TableView,并将属性注册到每个TableColumns。内部数据的编辑在TableView中反映得很好 然而,对于ListView,情况就不同了。除非我关闭框架并再次打开,否则不会立即显示更改 我的ListView由操作步骤组成。注意,我使用了javafxbean属性 package application.objects; import java.time.LocalDate; import java.util.ArrayList; import java.uti

不久前,我创建了一个TableView,并将属性注册到每个TableColumns。内部数据的编辑在TableView中反映得很好

然而,对于ListView,情况就不同了。除非我关闭框架并再次打开,否则不会立即显示更改

我的ListView由操作步骤组成。注意,我使用了javafxbean属性

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

}
包application.objects;
导入java.time.LocalDate;
导入java.util.ArrayList;
导入java.util.function.IntPredicate;
导入javafx.beans.property.IntegerProperty;
导入javafx.beans.property.ObjectProperty;
导入javafx.beans.property.SimpleIntegerProperty;
导入javafx.beans.property.SimpleObject属性;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
公开课行动步骤{
私有属性actionStepID;
私有对象属性日期集,dateFinished;
私有财产的名称;
私有集成属性完成;
私人ArrayList评论;
公共操作步骤(字符串名称){
actionStepID=新的SimpleStringProperty();
stepName=新的SimpleStringProperty();
dateSet=新的SimpleObject属性();
dateFinished=新的SimpleObject属性();
完成=新的SimpleIntegerProperty();
stepName.setValue(名称);
}
公共void集合名(字符串名){
stepName.setValue(名称);
}
公共字符串getName(){
返回stepName.getValue();
}
公共StringProperty stepNameProperty(){
返回actionStepID;
}
公共无效集合id(字符串id){
actionStepID.setValue(id);
}
公共字符串getID(){
返回actionStepID.get();
}
public StringProperty actionStepIDProperty(){
返回actionStepID;
}
公共无效设置完成(整数百分比){
如果(百分比<0 | |百分比>100)
返回;
完成。设置(百分比);
}
公共int getCompletion(){
返回completion.get();
}
公共IntegerProperty completionProperty(){
返回完成;
}
public void setDateSet(LocalDate){
dateSet.set(日期);
}
public LocalDate getDateSet(){
return dateSet.get();
}
公共对象属性dateSetProperty(){
返回日期集;
}
public void setDateFinished(LocalDate){
dateFinished.set(日期);
}
public LocalDate getDateFinished(){
return dateFinished.get();
}
公共对象属性dateFinishedProperty(){
返回日期已完成;
}
公共字符串toString(){
返回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();
@FXML
私有列表视图操作步骤列表视图;
私有可观察列表步骤;
listOfSteps=FXCollections.observableArrayList();
actionStepsListView.setItems(步骤列表);
如果(计划!=null){
ArrayList arrayOfSteps=plan.getStepsArrayList();
对于(int i=0;i
为什么对ObservableList所做的更改不反映在ListView中?我注意到ListView调用每个对象的toString()在ListView中显示它们的值,而不是将其绑定到它们的属性

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的示例:

public class JavaFX_ListView extends Application {

    class MyObject {
        String day;
        int number;

        MyObject(String d, int n) {
            day = d;
            number = n;
        }

        String getDay() {
            return day;
        }

        int getNumber() {
            return number;
        }

        @Override
        public String toString() {

            return number + " " + day;
        }
    }

    ObservableList<MyObject> myList;

    // Create dummy list of MyObject
    private void prepareMyList() {
        myList = FXCollections.observableArrayList();
        myList.add(new MyObject("Sunday", 50));
        myList.add(new MyObject("Monday", 60));
        myList.add(new MyObject("Tuesday", 20));

    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("sample");
        prepareMyList();
        ListView<MyObject> listView = new ListView<>();
        listView.setItems(myList);

        Pane root = new Pane();
        root.getChildren().add(listView);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
        // testing
        Timer timer = new Timer();
        timer.schedule(new UpdateListTask(), 1000, 1000);
    }

    public static void main(String[] args) {
        launch(args);
    }

    // testing
    public class UpdateListTask extends TimerTask {
        @Override
        public void run() {
            Platform.runLater(new Runnable() {

                @Override
                public void run() {
                    myList.add(new MyObject("sample", Calendar.getInstance()
                            .getTime().getSeconds()));
                }
            });
        }
    }

}
公共类JavaFX\u ListView扩展了应用程序{
类MyObject{
弦日;
整数;
MyObject(字符串d,整数n){
d=d;
数字=n;
}
字符串getDay(){
回归日;
}
int getNumber(){
返回号码;
}
@凌驾
公共字符串toString(){
返回编号+“”+天;
}
}
可观察的糜棱岩;
//创建MyObject的虚拟列表
私有void prepareMyList(){
myList=FXCollections.observableArrayList();
添加(新的MyObject(“Sunday”,50));
添加(新的MyObject(“星期一”,60));
添加(新的MyObject(“星期二”,20));
}
@凌驾
公共无效开始(阶段primaryStage){
初级阶段。设置标题(“样本”);
prepareMyList();
ListView ListView=新建ListView();
setItems(myList);
窗格根=新窗格();
root.getChildren().add(listView);
原始阶段。设置场景(新场景(根,300250));
primaryStage.show();
//测试
定时器=新定时器();
timer.schedule(新的UpdateListTask(),1000,1000);
}
公共静态void main(字符串[]args){
发射(args);
}
//测试
公共类UpdateListTask扩展TimerTask{
@凌驾
公开募捐{
Platform.runLater(新的Runnable(){
@凌驾
公开募捐{
添加(新的MyObject(“示例”),Calendar.getInstance()
.getTime().getSeconds());
}
});
}
}
}

请注意,与使用
表视图中的单元格相比,您试图使用
列表视图中的单元格执行更复杂的操作。在
表格视图中
,单元格中显示的对象正在变化,因此单元格很容易观察到这一点。在
列表视图中
,您希望单元格在属于单元格中显示的对象的属性发生更改时注意到这些属性;这是一个进一步的步骤,所以您必须做一些额外的编码(虽然不会太多,正如您将看到的)

您可以创建一个自定义单元格工厂来绑定到
stepNameProperty()
,但这很棘手(您必须确保在
updateItem()
方法中从旧项中解除绑定/删除侦听器)

更简单的方法,你
   public final void setName(String name) {
      stepName.setValue(name);
   }



   public final String getName() {
      return stepName.getValue();
   }


   public StringProperty nameProperty() {
      return stepName;
   }
  listOfSteps = FXCollections.observableArrayList(
    actionStep -> new Observable[] { actionStep.nameProperty() } // the "extractor"
  );
  actionStepsListView.setItems(listOfSteps);
listOfSteps = FXCollections.observableArrayList(
    new Callback<ActionStep, Observable[]>() {
        @Override
        public Observable[] call(ActionStep actionStep) {
            return new Observable[] { actionStep.nameProperty() } ;
        }
    });
actionStepListView.setItems(listOfSteps);