转换器与过滤器不同:转换器指定如何将文本转换为值,而过滤器则过滤用户可能进行的更改。听起来您想要两者都有,但您希望过滤器更准确地过滤允许的更改。
我通常发现,如果接受更改,检查文本的新值是最容易的。您希望可选地包含一个-
,后跟任意数量的数字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));
您甚至可以为过滤器添加更多功能,让它以更智能的方式处理 -
,例如:
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);
} else {
change.setRange(0, 0);
}
return change ;
}
return null;
};
这将允许用户在任何时候按下-
,并切换整数的符号。
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;
};
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);
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);
}
}
教程
一份关于如何使用TextFormatter
的综合教程指南:
?
!本来想用-?([1-9]?|[1-9][0-9]*)
,但这个更简洁! - flakes