如何格式化文本字段javafx
Posted
技术标签:
【中文标题】如何格式化文本字段javafx【英文标题】:How to format a text field javafx 【发布时间】:2016-02-10 06:21:41 【问题描述】:我希望能够以 hh:mm:ss 格式在 javafx 文本字段中输入时间。我将如何格式化文本字段?我已经得到了正则表达式方法,所以它只接受数字作为输入:
public void format(TextField t, String regex)
TextFormatter<String> formatter = new TextFormatter<String>( change ->
change.setText(change.getText().replaceAll(regex, ""));
return change;
);
t.setTextFormatter(formatter);
我还有一种方法可以限制文本字段中允许的字符数量:
public void limitLength(int maxLength, TextField t)
t.lengthProperty().addListener(new ChangeListener<Number>()
@Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
if (newValue.intValue() > oldValue.intValue())
// Check if the new character is greater than LIMIT
if (t.getText().length() >= maxLength)
t.setText(t.getText().substring(0, maxLength));
);
但是,这些都不能帮助我获得我想要的时间格式。理想的情况是初始文本为 00:00:00,用户只能编辑数字,不能触摸冒号。如果我能够确保每个冒号之间有 2 位数字,那就太棒了,即用户应该无法在数字之间移动,例如 0:000:00。
感谢您的帮助。
【问题讨论】:
见***.com/questions/32613619/… 【参考方案1】:使用 SimpleDateFormat
已经有一个用于格式化日期的类,您可以将其与TextField
's textFormatter
一起使用:SimpleDateFormat
TextField tf = new TextField();
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
tf.setTextFormatter(new TextFormatter<>(new DateTimeStringConverter(format), format.parse("00:00:00")));
有关字符含义的更详细说明,请参阅 SimpleDateFormat
的 javadoc。
使用 3 个不同的文本字段
您还可以使用 3 个不同的 TextField
s 并删除背景和边框并将它们放入 HBox
以获得不可编辑的 :
s:
TextField hours = new TextField();
TextField minutes = new TextField();
TextField seconds = new TextField();
StringConverter<Integer> minSecConverter = new IntRangeStringConverter(0, 59);
minutes.setTextFormatter(new TextFormatter<>(minSecConverter, 0));
seconds.setTextFormatter(new TextFormatter<>(minSecConverter, 0));
hours.setTextFormatter(new TextFormatter<>(new IntRangeStringConverter(0, 23), 0));
prepareTextField(hours);
prepareTextField(minutes);
prepareTextField(seconds);
HBox fields = new HBox(hours, createLabel(),minutes, createLabel(), seconds);
fields.setPadding(new Insets(4));
fields.setStyle("-fx-background-color: white;");
public static void prepareTextField(TextField tf)
tf.setAlignment(Pos.CENTER);
tf.setBackground(Background.EMPTY);
tf.setBorder(Border.EMPTY);
tf.setPadding(Insets.EMPTY);
tf.setPrefColumnCount(2);
public static class IntRangeStringConverter extends StringConverter<Integer>
private final int min;
private final int max;
public IntRangeStringConverter(int min, int max)
this.min = min;
this.max = max;
@Override
public String toString(Integer object)
return String.format("%02d", object);
@Override
public Integer fromString(String string)
int integer = Integer.parseInt(string);
if (integer > max || integer < min)
throw new IllegalArgumentException();
return integer;
public static Label createLabel()
Label label = new Label(":");
label.setPrefWidth(3);
return label;
【讨论】:
【参考方案2】:我一直在使用这个简单的类,直到对应于 DatePicker 的 TimePicker 可用为止。这里的策略是在字段失去焦点时检查条目。如果它不匹配正则表达式(可选的秒数和可选的 AM、PM、am、pm),它会通过发出哔哔声、用格式正确的条目替换条目、请求焦点并突出显示条目来吸引用户的注意力。我将 validate() 公开,以便容器(例如,对话框)也可以在关闭之前检查有效性(例如,如果按 OK 按钮失去焦点):
public class TimeTextField extends TextField
public TimeTextField(String init)
super(init) ;
focusedProperty().addListener((o, oldV, newV) -> changed(newV));
public TimeTextField()
this("12:00 PM");
private void changed(boolean focus)
if (!focus)
if (!validate())
setText("12:00 PM");
selectAll();
requestFocus();
Toolkit.getDefaultToolkit().beep();
public boolean validate()
return getText()
.matches("(0?[1-9]|1[0-2]):[0-5][0-9](:[0-5][0-9])? ?[APap][mM]$");
【讨论】:
【参考方案3】:你应该自己插入':'。因为这样用户只能插入数字。在每两个数字之后,您在更改侦听器中插入“:”。另外很容易插入时间。
【讨论】:
如果用户删除了 ':' 那么他们将无法再次添加它。 是的,你是对的。 ':' 也应该是可能的。我已经为输入 IP 地址编写了一个 chaneg 侦听器,并且有一个“。”允许。以上是关于如何格式化文本字段javafx的主要内容,如果未能解决你的问题,请参考以下文章
如何禁用 TextArea (JavaFX) 中的文本选择?
JavaFX:如何从 GridPane 中动态创建的文本字段的值计算平均值?
如何使用 JavaFX 将选择框、复选框和文本字段实现为一个按钮 [关闭]