You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX 8 TextField:如何扩展支持小数、千位分隔与两位小数限制

Handling Currency-Formatted Inputs in JavaFX TextField

Got it, let's tweak your existing code to support proper currency-style inputs—think numbers like 201.21, 122.00, or 12,122.12, while enforcing two decimal places and valid thousand separators. The original code only checks for digits, so we need to add logic to handle valid formatting edge cases.

First: Manual Input Validation (User Types Commas/Decimals)

If you want users to type commas and decimals manually while enforcing valid patterns, here's the updated onKeyTyped handler:

// Allow currency-formatted numeric input (e.g., 12,122.12, 201.21, 122.00)
TextField txtPurchaseCost.setOnKeyTyped(e -> {
    char input = e.getCharacter().charAt(0);
    String currentText = txtPurchaseCost.getText();

    // Let control keys (backspace/delete) pass through
    if (Character.isISOControl(input)) {
        return;
    }

    // Check for duplicate decimal points
    long existingDecimals = currentText.chars().filter(c -> c == '.').count();
    if (input == '.' && existingDecimals >= 1) {
        e.consume();
        return;
    }

    // Validate decimal input: if we already have two decimal digits, block more
    if (currentText.contains(".")) {
        String decimalPart = currentText.split("\\.")[1];
        if (decimalPart.length() >= 2 && Character.isDigit(input)) {
            e.consume();
            return;
        }
    }

    // Validate thousand separators: only allow commas after every 3 digits (from right)
    if (input == ',') {
        // Block commas at start, end, or before decimal
        if (currentText.isEmpty() || !Character.isDigit(currentText.charAt(currentText.length() - 1)) || currentText.contains(".")) {
            e.consume();
            return;
        }
        // Check if adding a comma would be in the correct position
        String integerPart = currentText.replace(",", "");
        if ((integerPart.length() + 1) % 3 != 0) {
            e.consume();
            return;
        }
    }

    // Block any other non-digit, non-decimal, non-comma characters
    if (!Character.isDigit(input) && input != '.' && input != ',') {
        e.consume();
    }
});

Key Checks in This Code:

  • Single Decimal Point: Prevents users from typing more than one .
  • Two Decimal Limit: Stops input after two digits past the decimal
  • Valid Thousand Separators: Ensures commas are only placed after every 3 digits (e.g., 12,345 is allowed, 1,2345 is not)
  • Control Key Allowance: Lets backspace/delete work normally

Better Option: Auto-Formatting as User Types

For a smoother user experience, use a TextFormatter to automatically add thousand separators and enforce formatting without requiring users to type commas. This also strips invalid characters automatically:

// Set up a TextFormatter to auto-format currency input
TextFormatter<String> currencyFormatter = new TextFormatter<>(change -> {
    String newInput = change.getControlNewText();
    // Strip all non-digit/non-decimal characters first
    String cleanedInput = newInput.replaceAll("[^\\d.]", "");

    // Split into integer and decimal parts
    String[] parts = cleanedInput.split("\\.", 2);
    String integerPart = parts[0];
    String decimalPart = parts.length > 1 ? parts[1].substring(0, Math.min(parts[1].length(), 2)) : "";

    // Add thousand separators to the integer part
    if (integerPart.length() > 3) {
        StringBuilder formattedInteger = new StringBuilder();
        int digitCount = 0;
        // Iterate from right to left to place commas correctly
        for (int i = integerPart.length() - 1; i >= 0; i--) {
            formattedInteger.insert(0, integerPart.charAt(i));
            digitCount++;
            if (digitCount % 3 == 0 && i != 0) {
                formattedInteger.insert(0, ",");
            }
        }
        integerPart = formattedInteger.toString();
    }

    // Reconstruct the final formatted text
    String finalText = integerPart + (decimalPart.isEmpty() ? "" : "." + decimalPart);

    // Update the change object to use the formatted text
    change.setText(finalText);
    change.setRange(0, change.getControlText().length());
    change.setCaretPosition(finalText.length());
    change.setAnchor(finalText.length());

    return change;
});

// Attach the formatter to your TextField
txtPurchaseCost.setTextFormatter(currencyFormatter);

This formatter will:

  • Auto-add thousand separators as the user types numbers
  • Limit decimal input to exactly two digits
  • Strip any non-numeric/non-decimal characters automatically
  • Keep the caret at the end of the text for smooth typing

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:03:50