java 仅在微调控件中插入数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25885005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Insert only numbers in Spinner Control
提问by user1285928
I tested Spinner control in Java 8u40
我在 Java 8u40 中测试了 Spinner 控件
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class MainApp extends Application
{
public static void main(String[] args)
{
Application.launch(args);
}
@Override
public void start(Stage stage)
{
final Spinner spinner = new Spinner();
spinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 10000));
spinner.setEditable(true);
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(10));
int row = 0;
grid.add(new Label("Spinner:"), 0, row);
grid.add(spinner, 1, row);
Scene scene = new Scene(grid, 350, 300);
stage.setTitle("Hello Spinner");
stage.setScene(scene);
stage.show();
}
}
How I can only insert number into the spinner control field?
我如何只能在微调控件字段中插入数字?
Now I can insert numbers and text. Is there any example that can be used as example?
现在我可以插入数字和文本了。有什么例子可以作为例子吗?
回答by kleopatra
Not entirely certain about the requirement - assuming that you want to prevent the input of characters that wouldn't parse to a valid Number.
不完全确定要求 - 假设您想防止输入无法解析为有效数字的字符。
If so, usage of a TextFormatter in the Spinner's editor comes to the rescue: with it, you'll monitor any change of text and either accept or reject it. The decision is encapsulated inside the formatter's filter. A very simple version (there's definitely more to do, see Swing's DefaultFormatter)
如果是这样,在 Spinner 的编辑器中使用 TextFormatter 就派上用场了:有了它,您将监视文本的任何更改并接受或拒绝它。该决定封装在格式化程序的过滤器中。一个非常简单的版本(肯定还有更多的事情要做,请参阅 Swing 的 DefaultFormatter)
// get a localized format for parsing
NumberFormat format = NumberFormat.getIntegerInstance();
UnaryOperator<TextFormatter.Change> filter = c -> {
if (c.isContentChange()) {
ParsePosition parsePosition = new ParsePosition(0);
// NumberFormat evaluates the beginning of the text
format.parse(c.getControlNewText(), parsePosition);
if (parsePosition.getIndex() == 0 ||
parsePosition.getIndex() < c.getControlNewText().length()) {
// reject parsing the complete text failed
return null;
}
}
return c;
};
TextFormatter<Integer> priceFormatter = new TextFormatter<Integer>(
new IntegerStringConverter(), 0, filter);
spinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(
0, 10000, Integer.parseInt(INITAL_VALUE)));
spinner.setEditable(true);
spinner.getEditor().setTextFormatter(priceFormatter);
回答by Marcus Bleil
- because Spinner uses TextField as an editor, users can insert any String into spinner
- only after user hits the return key then Spinners model (SpinnerValueFactory implementation) validates users input
- 因为 Spinner 使用 TextField 作为编辑器,所以用户可以在 Spinner 中插入任何 String
- 只有在用户点击返回键后,Spinners 模型(SpinnerValueFactory 实现)才会验证用户输入
so you have to add validation to Spinners editor by code:
所以你必须通过代码向 Spinners 编辑器添加验证:
// imports omitted
public class MainApp extends Application {
protected static final String INITAL_VALUE = "0";
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
final Spinner spinner = new Spinner();
spinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 10000,
Integer.parseInt(INITAL_VALUE)));
spinner.setEditable(true);
EventHandler<KeyEvent> enterKeyEventHandler;
enterKeyEventHandler = new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
// handle users "enter key event"
if (event.getCode() == KeyCode.ENTER) {
try {
// yes, using exception for control is a bad solution ;-)
Integer.parseInt(spinner.getEditor().textProperty().get());
}
catch (NumberFormatException e) {
// show message to user: "only numbers allowed"
// reset editor to INITAL_VALUE
spinner.getEditor().textProperty().set(INITAL_VALUE);
}
}
}
};
// note: use KeyEvent.KEY_PRESSED, because KeyEvent.KEY_TYPED is to late, spinners
// SpinnerValueFactory reached new value before key released an SpinnerValueFactory will
// throw an exception
spinner.getEditor().addEventHandler(KeyEvent.KEY_PRESSED, enterKeyEventHandler);
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(10));
int row = 0;
grid.add(new Label("Spinner:"), 0, row);
grid.add(spinner, 1, row);
Scene scene = new Scene(grid, 350, 300);
stage.setTitle("Hello Spinner");
stage.setScene(scene);
stage.show();
}
}
- try with not numbers: code will replace spinners editor content with INITIAL_VALUE
- try with numbers out of border, spinners model will reset spinners editor to valid value
- 尝试不使用数字:代码将用 INITIAL_VALUE 替换微调器编辑器内容
- 尝试使用超出边界的数字,微调模型会将微调编辑器重置为有效值