JAVAFx文本框验证:十进制值。

5

我正在尝试限制小数数字的文本字段,我已经找到了整数验证的解决方案(在这里),但问题是我无法将以下代码转换为小数数字,例如324.23、4.3、4、2、10.43(只允许一个小数点)。

 vendorList_textField_remaining.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            if (!newValue.matches("\\d*")) {
                vendorList_textField_remaining.setText(newValue.replaceAll("[^\\d||.]", ""));
            }
        }
    });

我也在寻找其他解决方案。 谢谢。


我认为如果你想替换第二个“.”,你需要一个“向后查找”。 - JohnnyAW
1
什么是场景?请提供一个测试用例。另外,尝试使用.replaceAll("^(\\d*\\.)|\\D", "$1") - Wiktor Stribiżew
1
@WiktorStribiżew 嗯,也许 .replaceAll("^(\\d*\\.\\d*)\\.", "$1") 更好一些... - JohnnyAW
1
备选解决方案:DoubleTextField from scenebuider - Andrey M
Wiktor Stribizew的答案正常工作。我也尝试了JohnnyAW的正则表达式,但不符合我的要求。感谢大家,特别感谢Wiktor Stribizew。 - Faraz Sultan
显示剩余4条评论
5个回答

7

我遇到了相同的情况。我认为我已经找到了这个问题的解决方案。正则表达式必须被替换为一个新的表达式,并进行一些setText的更改。现在它可以很好地工作。以下是代码:

vendorList_textField_remaining.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            if (!newValue.matches("\\d*(\\.\\d*)?")) {
                vendorList_textField_remaining.setText(oldValue);
            }
        }
    });

2
感谢您的帮助。我已经通过解决方案(1)解决了我的问题。
vendorList_textField_remaining.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        if(!newValue.matches("\\d*(\\.\\d*)?")) {
            vendorList_textField_remaining.setText(oldValue);
        }
    }
});

1

jidefx-oss项目中有一些优秀的字段验证组件,其中包括一个用于十进制数的组件。


我已经从@WiktorStribizew的评论中得到了正确的答案,无论如何还是谢谢。 - Faraz Sultan

1
我尝试过这种方法: (1)在文本字段上设置一个事件处理程序 (2)调用处理程序中的实用方法来决定键是否有效
设置处理程序:
txtField_Rate.setOnKeyTyped(new EventHandler<KeyEvent>() 
{
    @Override
    public void handle(KeyEvent ke) 
    {
        String character = ke.getCharacter();
        String text = txtField_Rate.getText();

         if ( !LM_Utility.isValid_forDouble(text, character, 99.99) )
             ke.consume(); 
    }
});

需要2个实用函数:- (1)isValidForDouble
public static boolean isValid_forDouble( String oldText, String newChar, double limit )
{
    boolean valid = false;
    String newText = oldText + newChar;
    int maxDecimals = getDecimals(limit);
    int decimals = 0;

    if ( newChar.matches("[0-9]") )
    {
        decimals = getDecimals(newText);
        if ( Double.valueOf(newText) <= limit )
            if ( decimals <= maxDecimals )
                valid = true;     
    }

    if ( newChar.equals(".") )
    {
        if ( !oldText.contains(".") )
                valid = true;
    }                

    return valid;
} 

和 (2) getDecimals()

private static int getDecimals(String value)
{
    int integerPlaces = 0;
    int decimalPlaces = 0;

    if (value.contains("."))
    {
        integerPlaces = value.indexOf('.');
        decimalPlaces = value.length() - integerPlaces - 1;
    }

    return decimalPlaces;
}

0

我知道这是一个老问题,但我也遇到了同样的问题,并找到了更好的解决方案。我基于this answer创建了一个简单的十进制字段。

它可以处理具有负值的十进制数。即使您已经输入了一些数字,也可以放置和删除点或-,因此非常易于使用。

它还仅编译一次模式,以确保更好的性能(当使用text.matches("regex")时,每次键入字符时都会编译模式)。

当您声明这样的类时,您可以像标准JavaFX组件一样在fxml文件中使用它。

public class DecimalField extends TextField {

private static Pattern decimalPattern = Pattern.compile("[-]?[0-9]*(\\.[0-9]*)?");

@Override
public void replaceText(int start, int end, String text) {
    if (validate(start, text)) {
        super.replaceText(start, end, text);
    }
}

@Override
public void replaceSelection(String text) {
    if (validate(Integer.MAX_VALUE, text)) {
        super.replaceSelection(text);
    }
}

private boolean validate(int start, String text) {
    String currentText = isNull(getText()) ? "" : getText();
    if(start == 0) { //to handle "-1.1" or ".1" cases
        return decimalPattern.matcher(text + currentText).matches();  
    } else {
        return decimalPattern.matcher(currentText + text).matches();
    }
}

}

当您将模式更改为:"[-][0-9]"时,它也适用于整数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接