【问题标题】:JavaFX TextField Array max length of text valueJavaFX TextField Array 文本值的最大长度
【发布时间】:2016-07-15 07:32:21
【问题描述】:

我正在处理一个 JavaFX 项目,但在使用 TextField 控件时遇到了问题。我想将用户输入到每个 TextField 的字符限制为一个。如果您使用带有侦听器的单个文本字段,我找到了一个解决方案:

public static void addTextLimiter(final TextField tf, final int maxLength) {
tf.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
        if (tf.getText().length() > maxLength) {
            String s = tf.getText().substring(0, maxLength);
            tf.setText(s);
        }
    }
});

但问题是我有一个文本字段数组。你们可能知道我如何为 TextFieldArray 重写这个监听器吗?

数组列表实现:

static public TextField[] tfLetters = new TextField[37];

数组的初始化:

private void layoutNodes() {
    int letternummer = 0;
    for (int i = 1; i < 8; i++) {
        for (int j = 0; j < i + 1; j++) {
            this.tfLetters[letternummer] = new TextField("Letter " + i);
            this.add(tfLetters[letternummer], j, i);
            tfLetters[letternummer].setPadding(new Insets(5, 30, 5, 5));
            tfLetters[letternummer].setAlignment(Pos.CENTER);
            tfLetters[letternummer].setMinSize(10, 10);
            letternummer++;
        }

    }

我使用了给定的解决方案:

Arrays.asList(tfLetters).forEach(tfLetters -> GamePresenter.addTextLimiter(tfLetters,1));

GamePresenter 是编写 Listener 的视图的演示者。 在“GameView”视图中,我实现了文本字段数组。但是现在当我运行给定的解决方案时,我会出现以下 NullPointerException:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at be.kdg.letterpyramide.view.GameView.GamePresenter.addTextLimiter(GamePresenter.java:36)
at be.kdg.letterpyramide.view.GameView.GameView.lambda$layoutNodes$0(GameView.java:52)
at java.util.Arrays$ArrayList.forEach(Arrays.java:3880)

GameView 行:36

 tf.textProperty().addListener(new ChangeListener<String>() {

GameView 行:52

Arrays.asList(tfLetters).forEach(tfLetters -> GamePresenter.addTextLimiter(tfLetters,1));

旁注:我将它设为公开静态,以便我可以在我的 GamePresenter 中使用它。我对 Java 很陌生。

提前致谢!

【问题讨论】:

  • 假设你提到的数组是TextField[] tfArrayaddTextLimiterMain中实现:Arrays.asList(tfArray).forEach(tf -&gt; Main.addTextLimiter(tf, 1));
  • @DVarga 的解决方案在我看来是最简单的,因为 TextField 没有可以覆盖的默认监听器,监听器列表默认为空。
  • @Dvarga 我使用了你的解决方案,但我得到了 NullPointerException,我不知道为什么......
  • 用你试过的代码更新问题。
  • @DVarga 更新了! :)

标签: javafx textfield


【解决方案1】:

这是一个没有 GridPane 的解决方案,但这是一个将字段也添加到 GridPane 的简单过程。现在有了一个更好的 TextFormatter。

import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ChangeListenerDemo extends Application {

  @Override
  public void start(Stage primaryStage) {
    List<TextField> fields = createLimitedTextFields(9, 1);

    VBox box = new VBox();
    box.getChildren().addAll(fields);

    Scene scene = new Scene(box, 300, 250);
    primaryStage.setScene(scene);
    primaryStage.show();
  }

  private List<TextField> createLimitedTextFields(int num, int maxLength) {
    final List<TextField> fields = new ArrayList<>();

    final UnaryOperator<TextFormatter.Change> filter
            = (TextFormatter.Change change) -> {
       if (change.getControlNewText().length() > maxLength) {
             return null;
       }
       return change;
    };
    for (int i = 0; i < num; i++) {
      final TextField tf = new TextField();
      tf.setTextFormatter(new TextFormatter(filter));
      fields.add(tf);
    }
    return fields;
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
    launch(args);
  }
}

【讨论】:

  • 使用TextFormatter 通常是一种更可取的方法(对于 8u60 及更高版本),因为它可以在任何绑定属性更改之前捕获更改(甚至在它应用于TextField 的@ 987654325@财产,实际上)
  • 很好,但是...你确定getCaretPosition 是准确的吗?如果我在中间粘贴一些东西怎么办? (最大长度为 10,文本为“123456789”,我在“1”之后粘贴“abcdef”。插入符号的位置将小于 10,但总长度将大于 10)。我认为使用getControlNewText().length() 是最安全的,也可能是最直接的。
  • @sillyfly ...适用于 8u60 及更高版本? TextFormatter.Change 自 8u40 起有效。但这是一种豆类计数......
  • 没错,我把版本弄糊涂了:D 确实,大多数人总是使用主要版本的最新更新,但是每当在初始主要版本之后添加功能时,我发现最好指定,如果由于某种原因您被锁定到旧版本,或者可能只是忘记更新......
  • @sillyfly 是的,我从 7u45 开始使用 JavaFX,所以我有点过时了 :-)
猜你喜欢
  • 2013-05-08
  • 2013-02-16
  • 2019-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多