如何创建数字本地化(小数点分隔符)TextField?

时间:2014-09-15 15:33:18

标签: javafx javafx-8

我想创建一个将被本地化的数字TextField。

例如,在Excel中,如果您使用英语,如果使用键盘键入数字,则小数分隔符键将输入一个点“'”。 但如果你是法语,小数点分隔符将是逗号','

因此,在Excel中,TextField足够智能,可以检测您所处的区域设置,并调整您实际想要在TextField中打印的小数分隔符。

目前在JavaFX中,我还没有找到办法做到这一点。我正在考虑听取文本修改,并用逗号替换任何出现的点,如果我用法语检测到我的话。但这个假设是真的吗?

3 个答案:

答案 0 :(得分:1)

我建议继承TextField并重写insertTextreplace*方法。这将在文本更新之前处理文本输入;听取文字修改并修改它们将意味着你暂时无效"无效"文本字段中的文本属性,可能会在应用程序的其余部分中产生问题。

请注意,如果需要,您可以为默认(用户)java.text.DecimalFormatSymbols(或指定的Locale)创建Locale对象,并致电getDecimalSeparator()查找正确的小数分隔符。 (同样,您可以拨打getGroupingSeparator()。)

因此,为了证明概念,这远远不够强大,无法生产:

public class NumericTextField extends TextField {
    @Override
    public void insertText(int index, String text) {
        String fixedText = fixText(text);
        StringBuilder newText = new StringBuilder(getText().substring(0, index));
        newText.append(fixedText);
        if (index < getText().length()) {
            newText.append(getText().substring(index));
        }
        if (isValid(newText)) {
            super.insertText(index, fixedText);
        }
    }

    @Override 
    public void replaceText(int start, int end, String text) {
        String fixedText = fixText(text);
        StringBuilder newText = new StringBuilder(getText().substring(0, start));
        newText.append(fixedText);
        newText.append(getText().substring(end));
        if (isValid(newText)) {
            super.insertText(start, end, fixedText);
        }
    }

    @Override
    public void replaceText(IndexRange range, String text) {
        replaceText(range.getStart(), range.getEnd(), text);
    }


    private String fixText(String text) {
        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
        return text.replaceAll("\\.", Character.toString(symbols.getDecimalSeparator()));
    }

    private boolean isValid(String text) {
        // check that the text is a valid numeric representation (or partial representation)
    }
}

答案 1 :(得分:-1)

在文本字段“ setOnKeyPressed”和“ setOnKeyReleased”的事件中,可以从keyEvent中获取按下的键的代码,并且可以看到“”的键代码。从主键盘按下时对应于常数“ PERIOD”,而击键代码为“。”。从数字键盘上按对应于常量“ DECIMAL”。

从这个概念出发,我分享在这方面取得的最接近的成就,如果我按“。”。根据我的特殊需要,从数字键盘上将其替换为字符“,”。

totalAmountText.setOnKeyReleased((keyEvent) -> {
        if (keyEvent.getCode() == DECIMAL) {
            int pos = totalAmountText.getCaretPosition();
            totalAmountText.setText(totalAmountText.getText().replace(".", ","));
            totalAmountText.positionCaret(pos);
        }
    });

答案 2 :(得分:-1)

我正在附加一个新版本的代码,该代码从第一个答案的代码中借鉴了最佳实践:

    totalAmountText.setOnKeyReleased((keyEvent) -> {
        if (keyEvent.getCode() == DECIMAL) {
            int pos = totalAmountText.getCaretPosition();
            DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
            totalAmountText.setText(totalAmountText.getText().replace(".", 
                Character.toString(symbols.getDecimalSeparator())));
            totalAmountText.positionCaret(pos);
        }
    });