将标签文本绑定到可观察变量

问题描述 投票:0回答:1

仅作为背景,几年前我曾经编写过网页设计的内容,但出于所有意图和目的,我只是开始接触 Java(实际上是 3 天),所以尽量放轻松!整个程序只是跟踪点击、保存和加载它们,这基本上就是它要做的全部事情。这只是一个练习,事实证明,在过去的几天里,它对我来说已经足够了。

目标是让 Click.fxml 中的标签在点击次数增加时发生变化。我已经通过控制台验证了逻辑工作正常,但当计数值增加时,我似乎无法更新此标签。我已经知道我忽略或错过了一些非常简单的事情,或者只是对其中的工作原理有一个根本性的误解!

这是我目前所拥有的,基于阅读大量堆栈问题和文档:

点击.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<VBox
  xmlns="http://javafx.com/javafx/8"
  xmlns:fx="http://javafx.com/fxml"
      fx:controller="application.ViewModel">
  <Button text="Click 1x" onAction="#clicked1x" />
  <Button text="Click 5x" onAction="#clicked5x" />
  <Button text="Test" onAction="#test" />
  <Label fx:id="currentTotalLabel"/>
</VBox>

ViewModel.java

package application;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class ViewModel {
  public Counter counter = new Counter();
  public Label currentTotalLabel;
  public ObservableValue<? extends String> totalText =
      new SimpleStringProperty(this, "rand", getCurrentTotalText());

  public void initialize() {
    currentTotalLabel.textProperty().bind(totalText);

    totalText.addListener(new ChangeListener<String>() {
      public void changed(ObservableValue<? extends String> observable,
          String oldValue, String newValue) {
        System.out.println("changed: " + oldValue + " -> " + newValue);
      }
    });
  }

  @FXML
  private void clicked1x(ActionEvent event) {
    counter.setTotal(1);
    System.out.println("Clicked 1x; " + getCurrentTotalText());
  }

  @FXML
  private void clicked5x(ActionEvent event) {
    counter.setTotal(5);
    System.out.println("Clicked 5x; " + getCurrentTotalText());
  }

  @FXML
  public String getCurrentTotalText() {
    String currentTotalText = counter.getTotal().getValue() + " total clicks!";
    return currentTotalText;
  }

  @FXML
  private void test(ActionEvent event) {
    System.out.println(getCurrentTotalText());
  }
}

我尝试了很多其他方法来解决这个问题,并且我特意想使用绑定来实现这一点。我只是不知道我到底错在哪里。

java javafx javabeans
1个回答
3
投票

您共享的代码的问题是,当 Counter 值更改时,ViewModel 中的totalText 属性不会更新,并且 Label 未绑定到totalTextProperty。

要修复它,您可以尝试:

package application;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class ViewModel {

    private final Counter counter = new Counter();
    private final StringProperty totalText = new SimpleStringProperty();

    @FXML
    private Label currentTotalLabel;

    public void initialize() {
        totalText.set(getCurrentTotalText());
        currentTotalLabel.textProperty().bind(totalText);

        counter.totalProperty().addListener((observable, oldValue, newValue) -> {
            totalText.set(getCurrentTotalText());
        });
    }

    @FXML
    private void clicked1x(ActionEvent event) {
        counter.setTotal(1);
        System.out.println("Clicked 1x; " + getCurrentTotalText());
    }

    @FXML
    private void clicked5x(ActionEvent event) {
        counter.setTotal(5);
        System.out.println("Clicked 5x; " + getCurrentTotalText());
    }

    @FXML
    public String getCurrentTotalText() {
        return counter.getTotal() + " total clicks!";
    }

    @FXML
    private void test(ActionEvent event) {
        System.out.println(getCurrentTotalText());
    }
}

对于计数器,您可以使用:

package application;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;

public class Counter {
    private final IntegerProperty total = new SimpleIntegerProperty(0);

    public IntegerProperty totalProperty() {
        return total;
    }

    public int getTotal() {
        return total.get();
    }

    public void setTotal(int value) {
        total.set(getTotal() + value);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.