输入数字时分隔文本字段中的数字 (Javafx)
Seprating the digits in the textfiled while entering the numbers (Javafx)
我创建了一个简单的 javafx 程序。当我在文本文件中输入数字时,我想将数字三乘三分开。我使用了 Whosebug 链接中给出的两个解决方案 (How to format text of TextField? JavaFX , )
但 none 他们正在为我工作。第一个解决方案(set textformatter)对我没用(或者我可能无法以正确的方式使用它)但第二个解决方案有效但只接受 4 位数字,我在文本字段中输入的其他数字是与我输入时不带逗号的样式相同。
我想像这样分隔每三个数字:12,564,546,554
如果有人知道解决方案,请帮助我解决这个问题。
谢谢。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.text.DecimalFormat;
import java.text.ParsePosition;
public class DelimiterExample extends Application{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
TextField textField = new TextField();
HBox hBox = new HBox();
//solution one
DecimalFormat format = new DecimalFormat( "#,###" );
textField.setTextFormatter( new TextFormatter<>(c ->
{
if ( c.getControlNewText().isEmpty() )
{
return c;
}
ParsePosition parsePosition = new ParsePosition( 0 );
Object object = format.parse( c.getControlNewText(), parsePosition );
if ( object == null || parsePosition.getIndex() < c.getControlNewText().length() )
{
return null;
}
else
{
return c;
}
}));
// solution two
textField.textProperty().addListener((obs , oldVal , newVal)-> {
if (newVal.matches("\d*")) {
DecimalFormat formatter = new DecimalFormat("#,###");
String newvalstr = formatter.format(Float.parseFloat(newVal));
//System.out.println(newvalstr);
textField.setText(newvalstr);
}
});
hBox.getChildren().add(textField);
Scene scene = new Scene(hBox , 100 , 100);
primaryStage.setScene(scene);
primaryStage.show();
}
}
任何不是选择更改的修改都可以通过修改范围前的字符来修复:
final char seperatorChar = ',';
final Pattern p = Pattern.compile("[0-9" + seperatorChar + "]*");
textField.setTextFormatter(new TextFormatter<>(c -> {
if (!c.isContentChange()) {
return c; // no need for modification, if only the selection changes
}
String newText = c.getControlNewText();
if (newText.isEmpty()) {
return c;
}
if (!p.matcher(newText).matches()) {
return null; // invalid change
}
// invert everything before the range
int suffixCount = c.getControlText().length() - c.getRangeEnd();
int digits = suffixCount - suffixCount / 4;
StringBuilder sb = new StringBuilder();
// insert seperator just before caret, if necessary
if (digits % 3 == 0 && digits > 0 && suffixCount % 4 != 0) {
sb.append(seperatorChar);
}
// add the rest of the digits in reversed order
for (int i = c.getRangeStart() + c.getText().length() - 1; i >= 0; i--) {
char letter = newText.charAt(i);
if (Character.isDigit(letter)) {
sb.append(letter);
digits++;
if (digits % 3 == 0) {
sb.append(seperatorChar);
}
}
}
// remove seperator char, if added as last char
if (digits % 3 == 0) {
sb.deleteCharAt(sb.length() - 1);
}
sb.reverse();
int length = sb.length();
// replace with modified text
c.setRange(0, c.getRangeEnd());
c.setText(sb.toString());
c.setCaretPosition(length);
c.setAnchor(length);
return c;
}));
再次感谢@fabian.I 在这个问题上卡了两天。我还发现我可以用这个 code.Now 获得我想要的货币样式我有两个完美的解决方案。
textField.setOnKeyTyped(event -> {
String typedCharacter = event.getCharacter();
event.consume();
if (typedCharacter.matches("\d*")) {
String currentText =
textField.getText().replaceAll("\.","").replace(",", "");
long longVal = Long.parseLong(currentText.concat(typedCharacter));
textField.setText(new DecimalFormat("#,##0").format(longVal));
}
});
请大家不要重新发明轮子。 class javafx.util.converter.NumberStringConverter
为我们做了所有需要的工作:
TextField numberField = new TextField();
TextFormatter<Number> textFormatter = new TextFormatter<>(new NumberStringConverter());
numberField.setTextFormatter(textFormatter);
NumberStringConverter 是你的朋友 ;),如果你想在文本字段上收听正确的数字变化,只需使用下一个 textFormatter 属性(原谅对 textField 对象的直接方法调用):
textFormatter.valueProperty(); //Returns ObjectProperty<Number>
然后你可以检索任何类型的数字 subclass (number.intValue(), number.floatValue(), etc), and ChangeListener 只有在用户写入有效数值时才会被触发。
如果您想手动为文本字段设置数值:
float value = 1000f; //or any type of Number subclass
textFormatter.setValue(value);
P.D:NumberStringConverter 具有 Locale 属性,可以更改该属性以应用所需国家/地区的适当格式。
我创建了一个简单的 javafx 程序。当我在文本文件中输入数字时,我想将数字三乘三分开。我使用了 Whosebug 链接中给出的两个解决方案 (How to format text of TextField? JavaFX ,
但 none 他们正在为我工作。第一个解决方案(set textformatter)对我没用(或者我可能无法以正确的方式使用它)但第二个解决方案有效但只接受 4 位数字,我在文本字段中输入的其他数字是与我输入时不带逗号的样式相同。
我想像这样分隔每三个数字:12,564,546,554 如果有人知道解决方案,请帮助我解决这个问题。 谢谢。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.text.DecimalFormat;
import java.text.ParsePosition;
public class DelimiterExample extends Application{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
TextField textField = new TextField();
HBox hBox = new HBox();
//solution one
DecimalFormat format = new DecimalFormat( "#,###" );
textField.setTextFormatter( new TextFormatter<>(c ->
{
if ( c.getControlNewText().isEmpty() )
{
return c;
}
ParsePosition parsePosition = new ParsePosition( 0 );
Object object = format.parse( c.getControlNewText(), parsePosition );
if ( object == null || parsePosition.getIndex() < c.getControlNewText().length() )
{
return null;
}
else
{
return c;
}
}));
// solution two
textField.textProperty().addListener((obs , oldVal , newVal)-> {
if (newVal.matches("\d*")) {
DecimalFormat formatter = new DecimalFormat("#,###");
String newvalstr = formatter.format(Float.parseFloat(newVal));
//System.out.println(newvalstr);
textField.setText(newvalstr);
}
});
hBox.getChildren().add(textField);
Scene scene = new Scene(hBox , 100 , 100);
primaryStage.setScene(scene);
primaryStage.show();
}
}
任何不是选择更改的修改都可以通过修改范围前的字符来修复:
final char seperatorChar = ',';
final Pattern p = Pattern.compile("[0-9" + seperatorChar + "]*");
textField.setTextFormatter(new TextFormatter<>(c -> {
if (!c.isContentChange()) {
return c; // no need for modification, if only the selection changes
}
String newText = c.getControlNewText();
if (newText.isEmpty()) {
return c;
}
if (!p.matcher(newText).matches()) {
return null; // invalid change
}
// invert everything before the range
int suffixCount = c.getControlText().length() - c.getRangeEnd();
int digits = suffixCount - suffixCount / 4;
StringBuilder sb = new StringBuilder();
// insert seperator just before caret, if necessary
if (digits % 3 == 0 && digits > 0 && suffixCount % 4 != 0) {
sb.append(seperatorChar);
}
// add the rest of the digits in reversed order
for (int i = c.getRangeStart() + c.getText().length() - 1; i >= 0; i--) {
char letter = newText.charAt(i);
if (Character.isDigit(letter)) {
sb.append(letter);
digits++;
if (digits % 3 == 0) {
sb.append(seperatorChar);
}
}
}
// remove seperator char, if added as last char
if (digits % 3 == 0) {
sb.deleteCharAt(sb.length() - 1);
}
sb.reverse();
int length = sb.length();
// replace with modified text
c.setRange(0, c.getRangeEnd());
c.setText(sb.toString());
c.setCaretPosition(length);
c.setAnchor(length);
return c;
}));
再次感谢@fabian.I 在这个问题上卡了两天。我还发现我可以用这个 code.Now 获得我想要的货币样式我有两个完美的解决方案。
textField.setOnKeyTyped(event -> {
String typedCharacter = event.getCharacter();
event.consume();
if (typedCharacter.matches("\d*")) {
String currentText =
textField.getText().replaceAll("\.","").replace(",", "");
long longVal = Long.parseLong(currentText.concat(typedCharacter));
textField.setText(new DecimalFormat("#,##0").format(longVal));
}
});
请大家不要重新发明轮子。 class javafx.util.converter.NumberStringConverter
为我们做了所有需要的工作:
TextField numberField = new TextField();
TextFormatter<Number> textFormatter = new TextFormatter<>(new NumberStringConverter());
numberField.setTextFormatter(textFormatter);
NumberStringConverter 是你的朋友 ;),如果你想在文本字段上收听正确的数字变化,只需使用下一个 textFormatter 属性(原谅对 textField 对象的直接方法调用):
textFormatter.valueProperty(); //Returns ObjectProperty<Number>
然后你可以检索任何类型的数字 subclass (number.intValue(), number.floatValue(), etc), and ChangeListener 只有在用户写入有效数值时才会被触发。
如果您想手动为文本字段设置数值:
float value = 1000f; //or any type of Number subclass
textFormatter.setValue(value);
P.D:NumberStringConverter 具有 Locale 属性,可以更改该属性以应用所需国家/地区的适当格式。