当前位置: 首页 > 知识库问答 >
问题:

将列表元素绑定到标签

施季
2023-03-14

当我试图将一个列表元素绑定到JavaFX标签时,我遇到了一个问题。如果项目不在列表中,我没有问题。

垃圾收集器是这个问题的原因吗?

Controller.class:(fxml文件的控制器)

public class Controller implements Initializable {
  private final Context context = Context.getInstance();
  private List<Label> labels;

  public void initialize() {
    labels = new ArrayList<>();
    
    for (int i = 0; i < context.getComponents().get(i).size(); i++) {
      labels.add(new Label(context.getComponent().get(i).toString()));
      
      labels.get(i).textProperty().bind(context.getComponents().get(i));

      gridPane.add(labels.get(i), 0, i); // The GridPane on the FXML
    }
  }
}

Context.java:(刷新变量的类)

public final class Context implements StatusEventListener, MssEventListener {
  private final List<StringProperty> components;
  
  public static Context getInstance() {
    return SingletonHandler.instance;
  }

  private Context() {
    super();
    components = new ArrayList<>();
    for (String component : new InstallProgress().getListInstallingItem()) {
      components.add(new SimpleStringProperty(component));
    }
  }

  public List<StringProperty> getComponents() {
    return components;
  }

  // Reset the list
  public void setComponents(final List<String> components) {
    this.components.clear();
    for (String component : components) {
      this.components.add(new SimpleStringProperty(component));
    }
  }

  private static class SingletonHandler {
        private static final Context instance = new Context();
        
        private SingletonHandler() {
            super();
        }
    }
}

要刷新标签,我使用Context.setComponents(

如果我刷新Context上的StringProperty组件。java,显示屏显示该变量的新值。

有没有人有解决这个问题的想法?

提前致谢


共有1个答案

岑毅庵
2023-03-14
匿名用户

绑定将每个标签的文本绑定到上下文(模型)中相应的< code>StringProperty。如果替换上下文中的整个< code>StringProperty,标签的文本仍然绑定到旧的< code>StringProperty,而不是替换它的那个属性(不更新绑定)。

(如果您没有在任何地方保留对旧StringProperty的引用,它将符合垃圾回收机制的条件。绑定使用弱侦听器(这反过来又使用对它们正在观察的对象的弱引用),因此您的绑定不会阻止StringProperty被垃圾回收。不过,这不是问题的原因;问题只是您的标签文本没有绑定到您在setComponents(…)方法中创建的新StringProperty。)

您在这里的最佳选择是使用可观察列表

public final class Context implements StatusEventListener, MssEventListener {
  private final ObservableList<String> components;
  
  public static Context getInstance() {
    return SingletonHandler.instance;
  }

  private Context() {
    super();
    components = FXCollections.observableArrayList<>(new InstallProgress().getListInstallingItem());

  }

  public ObservableList<String> getComponents() {
    return components;
  }

  // Reset the list
  public void setComponents(final List<String> components) {
    this.components.setAll(components);
  }

  private static class SingletonHandler {
        private static final Context instance = new Context();
        
        private SingletonHandler() {
            super();
        }
    }
}

现在您的视图类可以只观察列表。我在这里添加了对列表更改大小的处理,您的原始代码不支持:

public class Controller implements Initializable {
  private final Context context = Context.getInstance();
  private List<Label> labels;

  public void initialize() {
    labels = new ArrayList<>();
    
    updateLabelsFromContext();
    context.getComponents().addListener((Change<? extends String> c) ->
      updateLabelsFromContext());
  }

  private void updateLabelsFromContext() {
    List<String> components = context.getComponents();
    for (int i=0; i < labels.size() && i < components.size(); i++) {
      labels.get(i).setText(components.get(i));
    }

    // remove excess labels:
    
    for (int i=components.size(); i<labels.size(); i++) {
      gridPane.getChildren().remove(labels.get(i));
    }
    if (components.size() < labels.size()) {
      labels.subList(components.size(), labels.size()).clear();
    }

    // add any new labels needed:    
    for (int i = labels.size(); i<components.size(); i++) {
      Label label = new Label(components.get(i));
      labels.add(label);
      gridPane.add(label, 0, i);
    }
  }
}

如果保证上下文中列表的大小始终相同,则可以这样做

public class Controller implements Initializable {
  private final Context context = Context.getInstance();
  private List<Label> labels; // may not be needed

  public void initialize() {
    labels = new ArrayList<>();
    for (int i = 0; i<context.getComponents().size(); i++) {
      Label label = new Label();
      labels.add(label); // may not be needed
      label.textProperty().bind(Bindings.valueAt(context.getComponents(),i);
      gridPane.add(label, 0, i);
    }        
    
  }


}

 类似资料:
  • 如何在Spring MVC中将输入元素绑定到数组列表元素? 视图模型: 模型属性: 控制器 然后,在jsp中,我有4个隐藏的输入,它们表示evaluatedId、evaluatorId、evoluatorName和evaluatedName的字段- 更新: 通过此更新,我收到以下错误:

  • 本文向大家介绍aurelia 绑定到选择元素,包括了aurelia 绑定到选择元素的使用技巧和注意事项,需要的朋友参考一下 示例 字符串数组 在选择下拉列表中选择一个值并提供字符串数组时,所选值将作为字符串绑定到选择元素的value属性,我们可以使用字符串插值显示该字符串。 对象数组 与上面的示例不同,当提供对象数组时,在下拉列表中选择一个值时,绑定到该特定选项的模型就是所提供的对象。      

  • 问题内容: 我想避免。我该怎么办? 问题答案: 您可以在迭代本身期间使用支持remove / add方法的。

  • 问题内容: 我想将select元素绑定到对象列表-这很容易: 在这种情况下,似乎是一个数字-所选项目的ID。 但是,我实际上想绑定到country对象本身,所以它是对象,而不仅仅是id。我试图像这样更改选项的值: 但这似乎不起作用。它似乎在我的对象中放置了一个对象,但是没有放置我期望的对象。您可以在我的Plunker示例中看到这一点。 我还尝试绑定到change事件,以便可以根据所选的id自己设置

  • 问题内容: 我正在尝试找出如何阻止 DOM 元素以角度限制来自合并范围的数据。 我知道您可以使用if语句和所有方法来执行此操作,但是是否有一种真正而永久的方法来停止以角度绑定元素但保留添加的内容? 所以说我有这个 我更改了模型,以便div更改为此。 然后,我单击将其解除绑定的按钮,因此,如果将模型更改为,则不需要与以前相同。这个 我知道还有许多其他方法可以执行此操作,但是我不知道要真正地解除绑定元

  • 我有一个返回列表的函数。我试图在drools when子句中调用此函数,并将其绑定到名为l1的变量。如果像这样绑定变量,则子句不会执行。然而,如果我以类似的方式绑定映射,则执行then子句中的语句。我正在使用最新版本的drools。 这是代码 这里规则'test1'执行并打印值。但是我没有看到规则'test2'的任何输出。 任何帮助都将不胜感激。