Java 这种使用JTable默认单元格编辑器验证文本的简单方法不起作用。有人能帮助理解为什么吗?

Java 这种使用JTable默认单元格编辑器验证文本的简单方法不起作用。有人能帮助理解为什么吗?,java,swing,jtable,Java,Swing,Jtable,在让用户结束编辑之前,我想验证在JTable单元格中输入的数据是否正确。在Oracle教程中的此链接处 这听起来很简单。摘录说 当默认编辑器尝试创建与单元格列关联的类的新实例时,会自动检查用户输入的字符串。默认编辑器使用以字符串作为参数的构造函数创建此实例。例如,在单元格类型为Integer的列中,当用户在“123”中键入时,默认编辑器使用与新整数(“123”)等效的代码创建相应的整数。如果构造函数抛出异常,单元格的轮廓将变为红色,并拒绝将焦点移出单元格。如果您实现了一个用作列数据类型的类,那么

在让用户结束编辑之前,我想验证在JTable单元格中输入的数据是否正确。在Oracle教程中的此链接处 这听起来很简单。摘录说

当默认编辑器尝试创建与单元格列关联的类的新实例时,会自动检查用户输入的字符串。默认编辑器使用以字符串作为参数的构造函数创建此实例。例如,在单元格类型为Integer的列中,当用户在“123”中键入时,默认编辑器使用与新整数(“123”)等效的代码创建相应的整数。如果构造函数抛出异常,单元格的轮廓将变为红色,并拒绝将焦点移出单元格。如果您实现了一个用作列数据类型的类,那么如果您的类提供了一个采用String类型的单个参数的构造函数,则可以使用默认编辑器

为了测试这一点,我使用这个类创建了我能想到的最简单的案例:

    class CustomClass {
        int value = 0;
        public CustomClass(String newValue) throws NumberFormatException {
            value = Integer.parseInt(newValue);
            if(value<0 || value>100) throw new NumberFormatException("value out of range");
        }
        public String toString() {return value+"";}
    }
class自定义类{
int值=0;
公共CustomClass(字符串newValue)引发NumberFormatException{
value=Integer.parseInt(newValue);
如果(值100)抛出新的NumberFormatException(“值超出范围”);
}
公共字符串toString(){返回值+“”;}
}
其主要思想是,如果自定义类有一个只包含字符串的构造函数和一个toString()方法,那么它应该可以工作。我使用CustomClass作为第一列的类型来设置表。它不会产生预期或期望的结果。任何编辑这些单元格的尝试都会导致该单元格显示为红色,并且无法完成编辑。如果输入的数据不正确,这是所描述的行为。 情况就是这样:

我知道还有很多其他的方法可以做到这一点。但是这个方法很有吸引力,因为它提供了使用默认编辑器和渲染器的希望,而在自定义类中只需要很少的额外工作(无论如何我都需要)。但它似乎不像广告宣传的那样有效。我希望被证明是错的;-)

完整的程序粘贴在下面。添加了一些打印以帮助我了解正在发生的事情,但它们从未在预期的时间打印。也就是说,似乎没有调用构造函数和toString()方法来验证和返回输入的文本。有人知道为什么吗?谢谢

--------------完整的测试程序-------------

导入java.awt.EventQueue;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.table.DefaultTableModel;
最终公共类TestCodeGUI{
私有JFrame;
专用JTable表;
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
试一试{
TestCodeGUI窗口=新建TestCodeGUI();
window.frame.setVisible(true);
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
公共TestCodeGUI(){
初始化();
}
私有void初始化(){
frame=新的JFrame();
框架.立根(100100370168);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JScrollPane scrollPane=新的JScrollPane();
滚动窗格.立根(10,11,330,103);
frame.getContentPane().add(滚动窗格);
table=新的JTable();
scrollPane.setViewportView(表);
table.setModel(新的DefaultTableModel(
新对象[][]{
{new CustomClass(“00”)、Integer.parseInt(“01”)、“02”},
{new CustomClass(“10”)、Integer.parseInt(“11”)、“12”},
{new CustomClass(“20”)、Integer.parseInt(“21”)、“22”},
{new CustomClass(“30”)、Integer.parseInt(“31”)、“32”},
},
新字符串[]{
“第0列”、“第1列”、“第2列”
}
) {
类[]列类型=新类[]{
CustomClass.class、Integer.class、String.class
};
公共类getColumnClass(int columnIndex){
返回columnTypes[columnIndex];
}
});
System.out.println(“初始化完成”);
}
}
类自定义类{
int值=0;
公共CustomClass(字符串newValue)引发NumberFormatException{
System.out.println(“带有\''+newValue+''\''的CustomClass构造函数);
value=Integer.parseInt(newValue);
如果(值100)抛出新的NumberFormatException(“值超出范围”);
}
公共字符串toString(){
字符串s=值+“”;
System.out.println(“CustomClass toString返回\”+s+“\”);
返回s;
}
}

查看JTable类的源代码,您将在其中找到
GenericEditor
类,它是表的默认编辑器。
stopCellEditing()
方法负责设置红色边框

我试图用以下代码复制类中的
stopCellEditing()
逻辑:

System.out.println("Initialize complete");
System.out.println(table.getDefaultEditor(Object.class));
System.out.println(table.getDefaultEditor(CustomClass.class));

Class[] argTypes = new Class[]{String.class};
java.lang.reflect.Constructor constructor;
//Class<?> type = table.getColumnClass(column);
Class<?> type = CustomClass.class;

//String s = (String)super.getCellEditorValue();
String s = "25";

try
{
    //SwingUtilities2.checkAccess(constructor.getModifiers());
    constructor = type.getConstructor(argTypes);
    Object value = constructor.newInstance(new Object[]{s});
    System.out.println(value + " : " + value.getClass());
}
catch (Exception e)
{
    System.out.println(e);
    //((JComponent)getComponent()).setBorder(new LineBorder(Color.red));
    //return false;
}
System.out.println(“初始化完成”);
System.out.println(table.getDefaultEditor(Object.class));
System.out.println(table.getDefaultEditor(CustomClass.class));
类[]argTypes=新类[]{String.Class};
java.lang.reflect.Constructor;
//类类型=table.getColumnClass(列);
类别类型=CustomClass.Class;
//字符串s=(字符串)super.getCellEditorValue();
字符串s=“25”;
尝试
{
//SwingUtilities2.checkAccess(constructor.getModifiers());
constructor=type.getConstructor(argTypes);
Object value=constructor.newInstance(新对象[]{s});
System.out.println(value+”:“+value.getClass());
}
捕获(例外e)
{
系统。
System.out.println("Initialize complete");
System.out.println(table.getDefaultEditor(Object.class));
System.out.println(table.getDefaultEditor(CustomClass.class));

Class[] argTypes = new Class[]{String.class};
java.lang.reflect.Constructor constructor;
//Class<?> type = table.getColumnClass(column);
Class<?> type = CustomClass.class;

//String s = (String)super.getCellEditorValue();
String s = "25";

try
{
    //SwingUtilities2.checkAccess(constructor.getModifiers());
    constructor = type.getConstructor(argTypes);
    Object value = constructor.newInstance(new Object[]{s});
    System.out.println(value + " : " + value.getClass());
}
catch (Exception e)
{
    System.out.println(e);
    //((JComponent)getComponent()).setBorder(new LineBorder(Color.red));
    //return false;
}