【问题标题】:One ChangeListener for multiple TextFields in JavafxJavafx 中多个 TextField 的一个 ChangeListener
【发布时间】:2019-11-06 07:01:14
【问题描述】:

我想在我的应用程序中为多个 TextField 使用一个 ChangeListener。

我知道您可以创建一个侦听器对象并将其添加到所有 TextFields,然后您可以通过事件键检查哪个 TextField-Object 触发了事件。

有了 lamda 表达式,我可以对每个 TextField 使用它,不幸的是这不适合我的问题。我使用所有 TextField 的输入,所以一个 Listener 就足够了。

TextField textField = new TextField();
textField.textProperty().addListener((observable, oldValue, newValue) -> {
    System.out.println("textfield changed from " + oldValue + " to " + newValue);
});

【问题讨论】:

  • 创建一个实现接口javafx.beans.value.ChangeListener的类。创建这个类的一个实例。将它用作所有TextFields 方法addListener() 的参数。你想要一个例子吗?
  • 为什么不适合?请根据您的实际要求解释问题(最好使用minimal reproducible example),而不是假设解决方案的问题:)
  • ChangeListener<String> listener = (obs, ov, nv) -> { ... };?然后为每个TextField使用该实例?

标签: javafx listener textfield changelistener


【解决方案1】:

正如 Slaw 在他的评论中指出的那样,您可以轻松创建一个 ChangeListener,然后将其应用于您的每个 TextField 节点。

ChangeListener<String> listener = ((observable, oldValue, newValue) -> {
    System.out.println("TextField changed from " + oldValue + " to " + newValue + "!");
});

这是一个完整的示例,您可以运行它来查看它的实际效果:

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.Arrays;

public class ReusableListenerSample extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        // Simple Interface
        VBox root = new VBox(10);
        root.setAlignment(Pos.CENTER);
        root.setPadding(new Insets(10));

        // Create a ChangeListener that we will apply to multiple TextFields
        ChangeListener<String> listener = ((observable, oldValue, newValue) -> {
            System.out.println("TextField changed from " + oldValue + " to " + newValue + "!");
        });

        // Create some TextFields
        TextField txt1 = new TextField();
        TextField txt2 = new TextField();
        TextField txt3 = new TextField();

        // Now, we can add our preconfigured listener to each of the TextFields
        txt1.textProperty().addListener(listener);
        txt2.textProperty().addListener(listener);
        txt3.textProperty().addListener(listener);

        // Add our TextFields to the scene
        root.getChildren().addAll(txt1, txt2, txt3);

        // Show the stage
        primaryStage.setScene(new Scene(root));
        primaryStage.setTitle("ListViewSample Sample");
        primaryStage.show();

    }
}

现在,上面的示例并未表明 哪个 TextField 已更改。为了跟踪它,您可以创建自己的实现 ChangeListener&lt;String&gt; 的内部类并将您的 TextField(或任何其他数据)传递给它:

class MyChangeListener implements ChangeListener<String> {

    private final TextField myTextField;

    public MyChangeListener(TextField myTextField) {
        this.myTextField = myTextField;
    }

    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        System.out.println(myTextField + " changed from " + oldValue + " to " + newValue + "!");
    }
}

然后,只需将 MyChangeListener 的新实例添加到每个 TextField 即可:

txt1.textProperty().addListener(new MyChangeListener(txt1));

【讨论】:

  • 不知道到底是什么问题,很难解决,不是吗;)从问题中给出的稀疏细节来看,这些选项都不能满足其所有要求(挑剔和播放魔鬼的拥护者 ) 第一个不允许访问发送者——实际上,它允许是因为我们知道文本字段的 textProperty 是一个行为良好的属性,因此设置了它的 bean。第二个不是万能的……
  • 重复:不指示更改了哪个 TextField 是错误的,假设控件上的所有属性都是 readOnlyProperty 的有效实现;)
猜你喜欢
  • 2018-01-08
  • 2020-10-18
  • 2017-05-10
  • 1970-01-01
  • 2017-12-24
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多