简体   繁体   English

在JAVA中实现AbstractTableModel时发生异常?

[英]Exception in implementing AbstractTableModel in JAVA?

I have implemented a custom Table Model as follows: 我实现了一个自定义表模型,如下所示:

public class MyTableModel extends AbstractTableModel {
    ...
    ...
    @Override
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    ...
    ...
}

I am getting NullPointerException thrown by the above method, when I display a JTable having the above TableModel. 当我显示具有上述TableModel的JTable时,上述方法抛出NullPointerException。

I think that the exception is due to some empty cells in the database table. 我认为异常是由于数据库表中的一些空白单元格所致。

If the exception is due to empty cells in the database table, then how to get around with this problem? 如果异常是由于数据库表中的单元格为空,那么该如何解决该问题?

It is not mandatory for every column in the database to have some value. 不是强制数据库中的每个列都具有一定的值。 Some columns can contain nothing. 有些列不能包含任何内容。

One issue is why you are getting a null for these specific coordinates. 一个问题是为什么您要为这些特定坐标获取null。 If it is legitimate and you just want nothing special to be rendered, then what you need to do is null-check and return Object.class eg,: 如果它是合法的,并且您只希望不呈现任何特殊内容,那么您需要做的是空检查并返回Object.class,例如:

   public Class getColumnClass(int c) {
        Object o = getValueAt(0, c);
        if(o==null) return Object.class;
        return o.getClass()
    }

This will ensure that the default renderer is used, and since there is no value, nothing will be rendered. 这将确保使用默认渲染器,并且由于没有值,因此将不会渲染任何内容。

If cells can contain empty values, then calling getClass() on a null value will certainly give you the NPE. 如果单元格可以包含空值,那么对空值调用getClass()肯定会给您NPE。 Sure you can check for null, but your real problem is more subtle than that. 当然,您可以检查是否为空,但是实际的问题比那更微妙。

The TableModel interface specifies that getColumnClass(int) should return "the most specific superclass for all the cell values in the column." TableModel接口指定getColumnClass(int)应该返回“列中所有单元格值的最特定的超类”。 From the looks of things, you could be returning any number of class types for a single column, effectively breaking the TableModel contract. 从外观上看,您可能会为单个列返回任意数量的类类型,从而有效地打破了TableModel契约。

Typically, column types are static for a given set of table data, meaning the class for a column shouldn't change unless the underlying table data has changed. 通常,对于给定的一组表数据,列类型是静态的,这意味着除非基础表数据已更改,否则列的类不应更改。 I think it's important to ask why you need to return such a specific value. 我认为重要的是要问为什么您需要返回这样的特定值。

In the case where you want to render something specific for a given class type, you're better off rolling your own TableCellRenderer , and determining the Object type on a per-cell basis. 如果要呈现特定于给定类类型的内容,则最好滚动自己的TableCellRenderer ,并根据每个单元确定对象类型。 From there you can do any specific rendering as needed. 从那里可以根据需要执行任何特定的渲染。

Perhaps: 也许:

public Class getColumnClass(int c) {
        return (getValueAt(0, c) == null ? Object.class : getValue(0, c).getClass());
  }

I hope it helps you. 希望对您有帮助。

In addition to the answers so far: Assuming your model is backed by a List (as suggested in your previous question) you'll see an IndexOutOfBoundsException if attempting to render your JTable when the TableModel contains no rows (ie the List is empty). 除了到目前为止的答案之外:假设您的模型由List支持(如上一个问题中所建议),如果在TableModel包含行(即List为空)时尝试呈现JTable ,则会看到IndexOutOfBoundsException This is a nasty edge case (as I realise you're attempting to render a ResultSet - How do you know the ResultSet won't be empty?). 这是一个讨厌的情况(因为我意识到您正在尝试呈现ResultSet您怎么知道ResultSet不会为空?)。

To avoid this, why didn't you do what I suggested originally and determine each column's class from the ResultSetMetaData ? 为避免这种情况,您为什么不按照我最初的建议去从ResultSetMetaData确定每一列的类呢?

ResultSetMetaData does NOT provide any information about the class. ResultSetMetaData不提供有关该类的任何信息。 It does provide database-specific data types which don't automatically map over to Java classes (eg, "cidr" or "int8" in the PostgreSQL world) so this suggestion (which didn't include any source code, by the way) isn't actually helpful. 它确实提供了特定于数据库的数据类型,这些数据类型不会自动映射到Java类(例如,PostgreSQL世界中的“ cidr”或“ int8”),因此,此建议(顺便说一下,其中不包括任何源代码)实际上没有帮助。

Also, the comment "I think it's important to ask why you need to return such a specific value" by Jason Nichols shows general cluelessness about how the JTable class is used in the real world. 另外,Jason Nichols的注释“我认为重要的是要问为什么需要返回这样的特定值很重要”,这表明在现实世界中如何使用JTable类通常是毫无头绪的。

I'd like to find a solution to this problem where tables have zero rows, where I can still find out what the Java Class is that I should be using to render my cells for the entire column. 我想找到一个解决方案,该问题的解决方案是表的行数为零,在这里我仍然可以找到应该用于呈现整个列的单元格的Java类。 The idea that the output can change is based in yet more cluelessness about databases -- a column data type is specified in the definition of that column, and no matter what its contents are the data type doesn't change depending on which row you're looking it. 输出可以更改的想法基于对数据库的更多了解-在该列的定义中指定了列数据类型,无论其内容是什么,数据类型都不会根据您所在的行而改变重新看。

Of course one of the challenges with databases is that column definitions may or may not permit NULL values, and anyone sub-classing JTable for this should understand this very basic premise and know how to test for this. 当然,数据库的挑战之一是列定义可能允许也可能不允许NULL值,为此,对JTable进行子类化的任何人都应该了解这个非常基本的前提并知道如何对此进行测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM