Javafx обнаруживает изменение текстового поля и определяет позицию каретки - PullRequest
0 голосов
/ 24 октября 2019

Я реализую логику автозаполнения в Javafx. TextField - для ввода данных пользователем, и каждый раз, когда он обновляется, слушатель срабатывает. И тогда выпадающее меню, которое является listView, покажет соответствующие результаты.

Итак, проблема в том, как я могу получить обновленную позицию каретки в TextField, когда прослушиватель textProperty находится в процессе?

Я сейчас использую textfield.getCaretPosition(), но этовернет только предыдущую позицию.

Любые входные данные будут оценены!

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

            @Override
            public void changed(ObservableValue<? extends String> observable,
                                String oldText, String newText) {

                // Following line will return previous caret position
                commandTextField.getCaretPosition();

                ...//autocomplete logic omitted
            }
        });

РЕДАКТИРОВАТЬ: Причина, по которой мне нужно получить позицию каретки, заключается в том, что мне нужнознать позицию, где ввод изменяется, и показывать предложения соответственно.

            textField.caretPositionProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
                caretPosition = newValue.intValue();
            });

            textField.textProperty().addListener((ChangeListener<String>) (observable, oldValue, newValue) -> {

                ...//autocomplete Logic
            }

В вышеупомянутом случае сначала будет вызываться прослушиватель textProperty, а затем caretPositionProperty, поэтому нет способаполучить обновленную позицию каретки в моем случае.

Ответы [ 2 ]

1 голос
/ 24 октября 2019

Это не предполагаемое использование API, но вы можете использовать TextFormatter, созданный с UnaryOperator<TextFormatter.Change> в качестве параметра. Обычно это используется для предотвращения / изменения нежелательных изменений в тексте, но в этом случае мы просто используем объект Change, чтобы получить нужные вам данные.

В следующем примере каждый «предлагает» возможные вариантыодин заменяет выбранный раздел какой-либо строкой:

@Override
public void start(Stage primaryStage) throws Exception {
    ListView<String> listView = new ListView<>();

    String[] replacements = { "foo", "bar", "42", "zap" };
    listView.getItems().setAll(replacements);

    TextField textField = new TextField();
    TextFormatter<?> formatter = new TextFormatter<>((UnaryOperator<TextFormatter.Change>) change -> {
        int a = change.getAnchor();
        int b = change.getCaretPosition();
        String newText = change.getControlNewText();

        String prefix = newText.substring(0, Math.min(a, b));
        String suffix = newText.substring(Math.max(a, b));

        listView.getItems().clear();

        for (String mid : replacements) {
            listView.getItems().add(prefix + mid + suffix);
        }

        // do not change anything about the modification
        return change;
    });
    textField.setTextFormatter(formatter);

    Scene scene = new Scene(new VBox(listView, textField));

    primaryStage.setScene(scene);
    primaryStage.show();
}

Есть еще много доступных свойств, включая текст, позиции carret и anchor перед изменением, см. javadoc .

0 голосов
/ 24 октября 2019

Добавить слушателя к caretPositionProperty.

    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.scene.Scene;
    import javafx.scene.control.TextField;
    import javafx.stage.Stage;

    public class TextFieldCaretApp extends Application {

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

        @Override
        public void start(Stage stage) throws Exception {            
            TextField textField = new TextField();
            Scene scene = new Scene(textField);
            stage.setScene(scene);
            stage.show();

            textField.caretPositionProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
                System.out.println("caretPosition=" + newValue);
            });

            textField.textProperty().addListener((ChangeListener<String>) (observable, oldValue, newValue) -> {
                System.out.println("text=" + newValue);
            });
        }
    }
...