带TextFormatter和/或UnaryOperator的JavaFX 8中整数的数字文本字段
我试图使用JavaFX8的TextFormatter为整数创建一个数字TextField 使用UnaryOperator的解决方案:带TextFormatter和/或UnaryOperator的JavaFX 8中整数的数字文本字段,java,javafx,textfield,numeric,formatter,Java,Javafx,Textfield,Numeric,Formatter,我试图使用JavaFX8的TextFormatter为整数创建一个数字TextField 使用UnaryOperator的解决方案: UnaryOperator<Change> integerFilter = change -> { String input = change.getText(); if (input.matches("[0-9]*")) { return change; } return null; }; m
UnaryOperator<Change> integerFilter = change -> {
String input = change.getText();
if (input.matches("[0-9]*")) {
return change;
}
return null;
};
myNumericField.setTextFormatter(new TextFormatter<String>(integerFilter));
myNumericField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter()));
UnaryOperator integerFilter=更改->{
字符串输入=change.getText();
如果(input.matches(“[0-9]*”){
回报变化;
}
返回null;
};
setTextFormatter(新的TextFormatter(integerFilter));
使用IntegerStringConverter的解决方案:
UnaryOperator<Change> integerFilter = change -> {
String input = change.getText();
if (input.matches("[0-9]*")) {
return change;
}
return null;
};
myNumericField.setTextFormatter(new TextFormatter<String>(integerFilter));
myNumericField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter()));
myNumericField.setTextFormatter(新的TextFormatter(新的IntegerStringConverter());
两种解决方案都有各自的问题。使用UnaryOperator,我只能像预期的那样输入0到9之间的数字,但我还需要输入负数,如“-512”,其中符号只允许在第一个位置。此外,我不希望像“00016”这样的数字仍然是可能的
IntegerStringConverter方法工作得更好:像“-16-123”这样的每个无效数字都不被接受,像“0123”这样的数字被转换为“123”。但转换仅在提交文本(通过按enter键)或文本字段失去焦点时发生
是否有办法在每次更新文本字段的值时使用IntegerStringConverter强制转换第二个方法?转换器与筛选器不同:转换器指定如何将文本转换为值,并且筛选器筛选器可由用户更改。这听起来像是两个都需要,但您希望过滤器能够更准确地过滤允许的更改 我通常发现,如果接受了更改,检查文本的新值是最容易的。您希望有一个
-
,后跟1-9
,后面有任意数字。允许空字符串很重要,否则用户将无法删除所有内容
所以你可能需要像
UnaryOperator<Change> integerFilter = change -> {
String newText = change.getControlNewText();
if (newText.matches("-?([1-9][0-9]*)?")) {
return change;
}
return null;
};
myNumericField.setTextFormatter(
new TextFormatter<Integer>(new IntegerStringConverter(), 0, integerFilter));
这将允许用户在任意点按-
,并切换整数的符号
SSCCE:
import java.util.function.UnaryOperator;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javafx.util.converter.IntegerStringConverter;
public class IntegerFieldExample extends Application {
@Override
public void start(Stage primaryStage) {
TextField integerField = new TextField();
UnaryOperator<Change> integerFilter = change -> {
String newText = change.getControlNewText();
if (newText.matches("-?([1-9][0-9]*)?")) {
return change;
} else if ("-".equals(change.getText()) ) {
if (change.getControlText().startsWith("-")) {
change.setText("");
change.setRange(0, 1);
change.setCaretPosition(change.getCaretPosition()-2);
change.setAnchor(change.getAnchor()-2);
return change ;
} else {
change.setRange(0, 0);
return change ;
}
}
return null;
};
// modified version of standard converter that evaluates an empty string
// as zero instead of null:
StringConverter<Integer> converter = new IntegerStringConverter() {
@Override
public Integer fromString(String s) {
if (s.isEmpty()) return 0 ;
return super.fromString(s);
}
};
TextFormatter<Integer> textFormatter =
new TextFormatter<Integer>(converter, 0, integerFilter);
integerField.setTextFormatter(textFormatter);
// demo listener:
textFormatter.valueProperty().addListener((obs, oldValue, newValue) -> System.out.println(newValue));
VBox root = new VBox(5, integerField, new Button("Click Me"));
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 300, 120);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
import java.util.function.UnaryOperator;
导入javafx.application.application;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.TextField;
导入javafx.scene.control.TextFormatter;
导入javafx.scene.control.TextFormatter.Change;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
导入javafx.util.StringConverter;
导入javafx.util.converter.IntegerStringConverter;
公共类IntegerFieldExample扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
TextField integerField=新的TextField();
一元运算符整型过滤器=更改->{
字符串newText=change.getControlNewText();
如果(newText.matches(“-?([1-9][0-9]*)?”){
回报变化;
}else如果(“-”.equals(change.getText())){
if(change.getControlText().startsWith(“-”){
change.setText(“”);
改变设置范围(0,1);
change.setCaretPosition(change.getCaretPosition()-2);
change.setAnchor(change.getAnchor()-2);
回报变化;
}否则{
改变设置范围(0,0);
回报变化;
}
}
返回null;
};
//计算空字符串的标准转换器的修改版本
//作为零而不是空:
StringConverter converter=新整数StringConverter(){
@凌驾
公共整数fromString(字符串s){
如果(s.isEmpty())返回0;
返回super.fromString;
}
};
TextFormatter TextFormatter=
新的文本格式化程序(转换器、0、整数过滤器);
integerField.setTextFormatter(textFormatter);
//演示侦听器:
textFormatter.valueProperty().addListener((obs,oldValue,newValue)->System.out.println(newValue));
VBox root=new VBox(5,integerField,new按钮(“单击我”);
根部设置对齐(位置中心);
场景=新场景(根,300,120);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
TextField txtpoint=new TextField();
txtpoint.textProperty().addListener(新的ChangeListener()){
@凌驾
public void已更改(ObservableValueSmart在数字组上使用?
!正在考虑-?([1-9]?|[1-9][0-9]*)
,但这更干净了!我非常感谢您的努力,您的解决方案工作得非常好!对于堆栈溢出,通常欢迎使用一些解释/使用说明。因为fx8u80这是错误的(您不能更改正在侦听的属性),请改用textFormatter