gpt4 book ai didi

java - 带有 TextFormatter 和/或 UnaryOperator 的 JavaFX 8 中用于整数的数字文本字段

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:51:55 30 4
gpt4 key购买 nike

我正在尝试使用 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/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com