我目前正在尝试构建一个与命令shell类似的应用程序.我想在javaFX文本字段中的用户输入文本之前显示我给它的路径(或至少是’>’字符).像这样:
我有它,以便当用户提交文本时文本字段将清除.提交后,它将字段的文本设置为我的路径以实现类似的效果,但用户仍然可以在输入文本时删除此路径.
我怎样才能使我的路径文本显示在字段中但用户无法删除它?
我试过这个,但它只是在提交后更新了插入位置:
textField.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
textField.positionCaret(textField.getLength());
}
});
解决方法:
您可以使用TextFormatter
过滤掉文本字段上的无效操作. TextFormatter有一个过滤器,用于过滤对文本字段的更改;您可以通过使过滤器返回null来否决任何更改.您描述的最简单的实现只会过滤掉文本字段的插入位置或锚点在固定文本结束之前的任何更改:
UnaryOperator<TextFormatter.Change> filter = c -> {
if (c.getCaretPosition() < prefix.length() || c.getAnchor() < prefix.length()) {
return null ;
} else {
return c ;
}
};
textField.setTextFormatter(new TextFormatter<String>(filter));
您可以在此处试验其他逻辑(例如,如果您希望用户能够选择固定文本).
这是一个SSCCE:
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.StackPane;
import javafx.stage.Stage;
public class TextFieldFixedPrefix extends Application {
private TextField createFixedPrefixTextField(String prefix) {
TextField textField = new TextField(prefix);
UnaryOperator<TextFormatter.Change> filter = c -> {
if (c.getCaretPosition() < prefix.length() || c.getAnchor() < prefix.length()) {
return null ;
} else {
return c ;
}
};
textField.setTextFormatter(new TextFormatter<String>(filter));
textField.positionCaret(prefix.length());
return textField ;
}
@Override
public void start(Stage primaryStage) {
TextField textField = createFixedPrefixTextField("/home/currentUser $");
StackPane root = new StackPane(textField);
Scene scene = new Scene(root, 300,40);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}