- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用 JavaFX 8 的 TextFormatter 为整数创建一个数字 TextField。
使用 UnaryOperator 的解决方案:
UnaryOperator<Change> integerFilter = change -> {
String input = change.getText();
if (input.matches("[0-9]*")) {
return change;
}
return null;
};
myNumericField.setTextFormatter(new TextFormatter<String>(integerFilter));
使用 IntegerStringConverter 的解决方案:
myNumericField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter()));
这两种解决方案都有各自的问题。使用 UnaryOperator,我只能按预期输入从 0 到 9 的数字,但我还需要输入负值,如“-512”,其中符号只允许出现在第一个位置。此外,我不想要像“00016”这样的数字,这仍然是可能的。
IntegerStringConverter 方法工作得更好:不接受任何无效数字,如“-16-123”,并将“0123”等数字转换为“123”。但只有在提交文本(通过按回车键)或 TextField 失去焦点时才会发生转换。
有没有办法在每次更新 TextField 的值时强制使用 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));
您甚至可以向过滤器添加更多功能,让它以更智能的方式处理 -
,例如
UnaryOperator<Change> integerFilter = change -> {
String newText = change.getControlNewText();
// if proposed change results in a valid value, return change as-is:
if (newText.matches("-?([1-9][0-9]*)?")) {
return change;
} else if ("-".equals(change.getText()) ) {
// if user types or pastes a "-" in middle of current text,
// toggle sign of value:
if (change.getControlText().startsWith("-")) {
// if we currently start with a "-", remove first character:
change.setText("");
change.setRange(0, 1);
// since we're deleting a character instead of adding one,
// the caret position needs to move back one, instead of
// moving forward one, so we modify the proposed change to
// move the caret two places earlier than the proposed change:
change.setCaretPosition(change.getCaretPosition()-2);
change.setAnchor(change.getAnchor()-2);
} else {
// otherwise just insert at the beginning of the text:
change.setRange(0, 0);
}
return change ;
}
// invalid change, veto it by returning null:
return null;
};
这将让用户在任何时候按下 -
并且它会切换整数的符号。
中南合作:
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);
}
}
关于java - 带有 TextFormatter 和/或 UnaryOperator 的 JavaFX 8 中用于整数的数字文本字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40472668/
我正在使用javafx.scene.control.TextFormatter将文本字段格式化为货币字段。下面显示了我的代码。 private static final double DEFAULT_
我遇到了 JavaFX textformatter 的问题。我想知道是我做错了什么还是 Java JDK 中有错误。 这是显示问题的代码: import javafx.application.Appl
我的教授说,对 TextFormatter 使用过滤器和转换器是“理想的”。我查看了他的示例并尝试了它们,但根本不明白为什么我们需要转换器。 来自docs : A Formatter describe
我正在使用 TextFormatter 制作 WPF 文本编辑器。我需要证明每个段落中的最后 行。 类似的东西: I need to justify the last line in each par
我正在使用 TextFormatter 制作 WPF 文本编辑器。我需要缩进每一段的第二行。 第二行的缩进宽度应与第一行第一个单词的宽度相同,包括第一个单词后的空格。类似的东西: Indent of
我正在编写一个 TextFormatter,用 HTML 标签替换特殊字符。 "_" = "" and "" "*" = "" and "" 所以..我的代码如下.. public String co
编辑 显然这是一个错误。我所做的报告可以找到here 。正如 @James_D 指出的,这不是绑定(bind)的问题,但在将文本设置为非空值后将其设置为 null 就足够了。 我在使用 JavaFX
我正在寻找一个示例,使用 Java8 u40 的新类 TextFormatter 将用户输入限制为仅数字和小数点。 http://download.java.net/jdk9/jfxdocs/java
我创建了一个自定义异常,其中包含与我们的应用程序有关的数据。我想确保在抛出异常并记录到事件日志时记录这些数据。 我尝试创建一个正在调用的自定义 TextFormatter,但不确定如何访问当前异常,以
我正在尝试使用 JavaFX 8 的 TextFormatter 为整数创建一个数字 TextField。 使用 UnaryOperator 的解决方案: UnaryOperator integerF
我有一个 TextField,它被赋予了一个 TextFormatter,它有一个过滤器,可以接受文本字段的输入,并确保它是 double 格式。然后它使用 DoubleStringConverter
我是一名优秀的程序员,十分优秀!