динамически добавлять текстовые поля с помощью слушателей - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь написать программу, похожую на приложение контактов на телефоне Android, используя javafx. В файле fxml у меня есть VBox, который содержит три текстовых поля, первые два поля для имени и фамилии, а третье для числа.

Теперь я хочу, чтобы программа работала, когда текстовое поле для числа заполнено хотя бы одним символом, другое текстовое поле, которое будет автоматически добавлено в VBox. (для другого номера).

и я хочу, чтобы то же самое произошло для следующего поля. и любое другое поле, которое следует, поэтому оно имеет рекурсивную форму.

Теперь единственный известный мне способ, который может это сделать, - это использование слушателя, но я понятия не имею, как создать такого рекурсивного слушателя. и слушатель старого поля должен быть удален, как только он выполнит свою работу, поэтому он не будет непрерывно создавать новые поля при вводе чего-либо в старое поле. но вы не можете удалить слушателя, находясь внутри него.

Есть ли способ сделать это?

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Зарегистрируйте ChangeListener для свойства text TextField s, которое добавляет / удаляет TextField на основе индекса каждый раз, когда текст меняется с пустого на непустой или наоборот.

public void addTextField(Pane parent) {
    TextField textField = new TextField();
    textField.textProperty().addListener((o, oldValue, newValue) -> {
        boolean wasEmpty = oldValue.isEmpty();
        boolean isEmpty = newValue.isEmpty();

        if (wasEmpty != isEmpty) {
            if (wasEmpty) {
                // append textfield if last becomes non-empty
                if (parent.getChildren().get(parent.getChildren().size() - 1) == textField) {
                    addTextField(parent);
                }
            } else {
                int tfIndex = parent.getChildren().indexOf(textField);
                if (tfIndex < parent.getChildren().size() - 1) {
                    // remove textfield if this is not the last one
                    parent.getChildren().remove(tfIndex);
                    parent.getChildren().get(tfIndex).requestFocus();
                }
            }
        }
    });

    parent.getChildren().add(textField);
}
VBox root = new VBox();
addTextField(root);
0 голосов
/ 24 апреля 2018

Лямбда-выражение не может ссылаться на себя, но анонимный внутренний класс может, поэтому, если вы реализуете свой слушатель как анонимный внутренний класс, вы можете достичь того, что вы хотите сделать:

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class DynamicTextFields extends Application {

    private TextField lastTextField ;

    @Override
    public void start(Stage primaryStage) {
        lastTextField = new TextField();
        VBox vbox = new VBox(5, lastTextField);
        ChangeListener<String> textFieldListener = new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) {
                lastTextField.textProperty().removeListener(this);
                lastTextField = new TextField();
                lastTextField.textProperty().addListener(this);
                vbox.getChildren().add(lastTextField);
            }

        };
        lastTextField.textProperty().addListener(textFieldListener);

        Scene scene = new Scene(new ScrollPane(vbox), 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...