如何格式化文本字段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 个不同的 TextFields 并删除背景和边框并将它们放入 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 将选择框、复选框和文本字段实现为一个按钮 [关闭]

如何在文本字段中格式化 java.time.LocalDate? [复制]

如何右对齐和格式化输入到 Strut2 文本字段中的金额?

输入时如何将文本字段格式设置为十进制?