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

JTable自定义单元格编辑器验证后无法退出编辑及弹窗异常问题

解决JTable自定义单元格编辑器的两个问题

你遇到的两个问题:输入有效值后单元格仍处于编辑状态,以及弹窗提示导致应用挂起,我来帮你逐一解决。

问题分析

  1. 有效值输入后单元格仍可编辑:你的stopCellEditing方法直接返回isValid,但没有调用父类的super.stopCellEditing(),这会导致DefaultCellEditor无法完成编辑状态的清理工作(比如移除编辑器组件、更新表格模型等),所以单元格看起来还处于编辑状态。
  2. 弹窗提示导致应用挂起:你使用null作为JOptionPane的父组件,这会让弹窗成为无主窗口,可能在后台显示,同时因为表格的编辑状态未处理完成,导致事件派发线程阻塞,应用挂起。

修改后的完整代码

import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;

public class DepartmentCellEditor extends DefaultCellEditor {
    public DepartmentCellEditor() {
        super(new JTextField());
    }

    @Override
    public boolean stopCellEditing() {
        JTable table = (JTable) getComponent().getParent();
        try {
            boolean isValid = true;
            String s = getCellEditorValue().toString();
            
            // 验证是否为3位数字
            if (s.length() == 3) {
                for (int i = 0; i < s.length(); i++) {
                    if (!Character.isDigit(s.charAt(i))) {
                        isValid = false;
                        break;
                    }
                }
            } else {
                isValid = false;
            }

            JTextField textField = (JTextField) getComponent();
            if (!isValid) {
                // 输入无效:设置红色边框,选中内容,保持焦点
                textField.setBorder(new LineBorder(Color.RED));
                textField.selectAll();
                textField.requestFocusInWindow();
                
                // 使用table作为父组件显示弹窗,避免后台挂起
                SwingUtilities.invokeLater(() -> {
                    JOptionPane.showMessageDialog(table, 
                        "Please enter a 3 digit number.", 
                        "Alert!", 
                        JOptionPane.ERROR_MESSAGE);
                });
                return false; // 不停止编辑
            } else {
                // 输入有效:恢复黑色边框,调用父类方法完成编辑停止
                textField.setBorder(new LineBorder(Color.BLACK));
                // 调用父类的stopCellEditing确保完成编辑状态清理
                return super.stopCellEditing();
            }
        } catch (ClassCastException exception) {
            JTextField textField = (JTextField) getComponent();
            textField.setBorder(new LineBorder(Color.RED));
            textField.selectAll();
            textField.requestFocusInWindow();
            
            SwingUtilities.invokeLater(() -> {
                JOptionPane.showMessageDialog((JTable) getComponent().getParent(), 
                    "Invalid input type.", 
                    "Alert!", 
                    JOptionPane.ERROR_MESSAGE);
            });
            return false;
        }
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        Component c = super.getTableCellEditorComponent(table, value, isSelected, row, column);
        ((JComponent) c).setBorder(new LineBorder(Color.BLACK));
        return c;
    }
}

关键修改点说明

  • 解决编辑状态未结束问题:当输入有效时,不再直接返回true,而是调用super.stopCellEditing(),让DefaultCellEditor完成编辑停止的所有必要操作,比如更新表格模型、移除编辑器组件,这样单元格就会正常退出编辑状态。
  • 解决弹窗挂起问题:
    • 使用table作为JOptionPane的父组件,确保弹窗在表格窗口的前方显示,不会跑到后台。
    • 用SwingUtilities.invokeLater()包裹弹窗代码,确保弹窗在事件派发线程的正确时机执行,避免阻塞编辑状态的处理流程。
  • 代码优化:将重复的JTextField获取逻辑提取出来,减少冗余代码。

这样修改后,输入3位有效数字时,单元格会正常退出编辑状态;输入无效值时,会显示弹窗提示,同时保持单元格的编辑状态和焦点,不会导致应用挂起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:42:48