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

JavaFX TextFormatter整数范围验证问题:TableView下限校验失效

JavaFX TableView 整数输入范围校验(100-500)修复方案

你的代码核心问题是输入过程中的中间值被直接拦截:比如用户输入"1"时,数值1小于100会被直接拒绝,导致根本无法输入完整的"100"。当前逻辑要求每一步输入后的数值都必须在100-500之间,但实际输入是逐步完成的,需要允许合法的中间输入,最终只限制完整数值在范围内。

修正后的校验逻辑

private static final int MIN_RANGE_VALUE = 100;
private static final int MAX_RANGE_VALUE = 500;

UnaryOperator<Change> flowFilter = change -> {
    String newText = change.getControlNewText();
    
    // 允许空输入,方便用户删除内容
    if (newText.isEmpty()) {
        return change;
    }
    
    // 只允许输入纯数字,过滤非数字字符
    if (!newText.matches("\\d+")) {
        return null;
    }
    
    try {
        int value = Integer.parseInt(newText);
        // 完整数值在范围内,直接允许
        if (value >= MIN_RANGE_VALUE && value <= MAX_RANGE_VALUE) {
            return change;
        } else {
            // 处理输入过程中的中间值:判断是否有可能扩展成合法数值
            if (newText.length() < 3) {
                // 长度为1时,只能是1-5(只有1xx到5xx才可能落在范围内)
                if (newText.length() == 1) {
                    char firstChar = newText.charAt(0);
                    return (firstChar >= '1' && firstChar <= '5') ? change : null;
                }
                // 长度为2时,允许10-50(10可扩展为100+,50可扩展为500;51+扩展后超上限,0-9扩展后不足下限)
                else if (newText.length() == 2) {
                    int twoDigitVal = Integer.parseInt(newText);
                    return (twoDigitVal >= 10 && twoDigitVal <= 50) ? change : null;
                }
            }
            // 长度≥3且不在范围内,直接拒绝
            return null;
        }
    } catch (NumberFormatException e) {
        // 已通过\\d+校验,理论不会触发
        return null;
    }
};

逻辑要点说明

  • 允许空输入:用户可以自由删除单元格内容
  • 过滤非数字:确保只能输入整数类型
  • 中间值判断:
    • 单数字只允许1-5,避免输入0、6-9这类无法扩展成合法数值的字符
    • 两位数允许10-50,既保证可以扩展为100-500,又拦截51-99(扩展后超上限)、0-9(扩展后不足下限)的无效输入
    • 三位数直接校验是否在100-500范围内,不符合则拒绝

单元格应用示例

将校验逻辑绑定到TableView可编辑单元格的示例代码:

TableColumn<YourDataModel, Integer> numberColumn = new TableColumn<>("数值列");
numberColumn.setCellValueFactory(new PropertyValueFactory<>("numberProperty"));

numberColumn.setCellFactory(col -> new TableCell<YourDataModel, Integer>() {
    private final TextField textField = new TextField();
    private final TextFormatter<Integer> textFormatter;

    {
        // 绑定校验逻辑
        textFormatter = new TextFormatter<>(new IntegerStringConverter(), null, flowFilter);
        textField.setTextFormatter(textFormatter);

        // 处理编辑提交
        textField.setOnAction(e -> commitEdit(textFormatter.getValue()));
        textField.focusedProperty().addListener((obs, oldFocus, newFocus) -> {
            if (!newFocus) {
                commitEdit(textFormatter.getValue());
            }
        });
    }

    @Override
    protected void updateItem(Integer item, boolean empty) {
        super.updateItem(item, empty);
        if (empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            if (isEditing()) {
                textField.setText(item.toString());
                setGraphic(textField);
                setText(null);
            } else {
                setText(item.toString());
                setGraphic(null);
            }
        }
    }

    @Override
    public void startEdit() {
        super.startEdit();
        textField.setText(getItem().toString());
        setGraphic(textField);
        setText(null);
        textField.requestFocus();
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();
        setText(getItem().toString());
        setGraphic(null);
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:13:15