首页 > 解决方案 > 如何在未聚焦之前获取 TextField 的最后一个插入符号位置?

问题描述

我试图制作一个可以在 TextField 中插入特殊字符的按钮,这是我最初的实现:

// input is a TextField
input.insertText(input.getCaretPosition(), "∞");

但是我发现它总是将文本插入到开头,然后经过一些尝试,我发现TextField的“unfocus”会caretPosition变为0。这不是我想要的,所以我尝试直接使用监听caretPosition属性像这样:

AtomicInteger caretPos = new AtomicInteger();
input.caretPositionProperty().addListener((obs, oldVal, newVal) -> {
    caretPos.set(newVal.intValue());
    System.out.println(newVal.intValue());
});

但问题是失去焦点时仍然会调用listen,它caretPos会再次重置为0。

标签: javajavafx

解决方案


caretPos如果文本字段失去焦点,只需避免更新:

AtomicInteger caretPos = new AtomicInteger();
input.caretPositionProperty().addListener((obs, oldVal, newVal) -> {
    if (input.isFocused()) {
        caretPos.set(newVal.intValue());
        System.out.println(newVal.intValue());
    }
});

这是一个完整的工作示例:

import java.util.concurrent.atomic.AtomicInteger;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TextFieldFocusTest extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        TextField input = new TextField();
        Button insertInfinity = new Button("∞");


        AtomicInteger caretPos = new AtomicInteger();
        input.caretPositionProperty().addListener((obs, oldVal, newVal) -> {
            if (input.isFocused()) {
                caretPos.set(newVal.intValue());
            }
        });

        insertInfinity.setOnAction(e -> {
            int pos = caretPos.get();
            input.insertText(pos, "∞");
            input.requestFocus();
            input.positionCaret(pos+1);
        });

        VBox root = new VBox(10);
        root.setPadding(new Insets(10,10,10,10));
        root.setAlignment(Pos.CENTER);
        root.getChildren().addAll(input, insertInfinity);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setWidth(400);
        primaryStage.setHeight(400);
        primaryStage.show();
    }

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

}

推荐阅读