当前位置: 首页 > 面试题库 >

ListView没有反映更改

令狐俊风
2023-03-14
问题内容

我创建了一个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;
   }

和其他属性访问器方法类似。(显然,字段的名称可以是您喜欢的任何名称,因为它们是私有的。)使get /
set方法成为最终方法是一种好习惯。

然后,使用提取器创建列表。提取器是将列表中的每个元素映射到Observable列表将要观察的s
数组的函数。如果这些值发生更改,它将向列表的观察者触发列表更新。由于您ActionSteptoString()方法引用了nameProperty(),因此我假设您要ListViewnameProperty()更改时进行更新。所以你想做

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


 类似资料:
  • 我创建了一个TableView,并为每个TableColumn注册了属性。内部数据的编辑可以很好地反映在TableView中。 然而,对于ListView,情况就不同了。除非我关闭框架并再次打开它,否则更改不会立即显示。

  • 问题内容: 我的文件夹中有JavaScript文件。Django可以很好地找到并加载它们,因此我认为我的选项配置没有任何问题。但是,有时候,当我对文件进行更改并保存时,使用该文件的Django模板不会反映这些更改- 使用浏览器检查javascript会在最后一次保存之前显示javascript。重新启动服务器没有任何作用,尽管重新启动计算机有时可以解决问题。我没有任何明确处理缓存的代码。有没有人经

  • 我只是无法在本地主机设置中获得要更改的php_info()值,或者相关的phpMyAdmin最大文件大小。 因此,我找到了phpinfo声明正在加载的PHP文件。我更改了三个参数: upload_max_filesize 贴纸最大尺寸 内存限制 保存文件,重启Apache和MySQL,重新加载phpinfo()页面...没有变化。 我也试着放一个。web根文件夹中的htaccess文件,其中包含对

  • 我有一个非常简单的Web服务实现,如下所示 } 我在我的实现类文件上运行了一个wsgen来生成JAXB类和WSDL(以及XSD) 尝试调用此方法时的SOAP响应如下 如果我想生成如下响应,我该怎么办 我确实尝试将生成的(由wsgen)JAXB响应类更改为具有@XmlType(name = “NameResponse”,namespace = “http://implementation/”)和@X

  • 问题内容: 我已经定义了一个模型,并通过创建了它的关联数据库。现在,我已经向模型添加了一些字段,我syncdb再次尝试了,但是没有输出出现。尝试从模板访问这些新字段时,出现“ No Such Column”异常,使我相信syncdb实际上并未更新数据库。这里正确的命令是什么? 问题答案: 似乎你需要的是迁移系统。South真的很棒,工作非常好,有一些自动化工具可以简化你的工作流程。 注意:sync

  • 本文向大家介绍Android中ListView的item点击没有反应的解决方法,包括了Android中ListView的item点击没有反应的解决方法的使用技巧和注意事项,需要的朋友参考一下 如果stu_item.xml里面包括button或者checkbox等控件,默认情况下list的item会失去焦点,导致无法响应item的事件,最常用的解决办法是在stu_item.xml的布局文件中设置de