Исключение в реализации AbstractTableModel в JAVA? - PullRequest
0 голосов
/ 04 февраля 2010

Я реализовал пользовательскую модель таблицы следующим образом:

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

Я получаю исключение NullPointerException вышеупомянутым методом, когда отображаю JTable с указанным выше TableModel.

Я думаю, что исключение связано с некоторыми пустыми ячейками в таблице базы данных.

Если исключение связано с пустыми ячейками в таблице базы данных, то как обойти эту проблему?

Не обязательно, чтобы каждый столбец в базе данных имел какое-либо значение. Некоторые столбцы могут не содержать ничего.

Ответы [ 5 ]

1 голос
/ 04 февраля 2010

Одна проблема заключается в том, почему вы получаете нулевое значение для этих конкретных координат. Если это допустимо, и вы просто хотите, чтобы ничего особенного не отображалось, то вам нужно выполнить нулевую проверку и вернуть Object.class, например:

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

Это обеспечит использование средства визуализации по умолчанию, а поскольку значения отсутствуют, ничто не будет отображаться.

1 голос
/ 04 февраля 2010

Если ячейки могут содержать пустые значения, то вызов getClass () для нулевого значения обязательно даст вам NPE. Конечно, вы можете проверить на ноль, но ваша реальная проблема более тонкая, чем эта.

Интерфейс TableModel указывает, что getColumnClass (int) должен возвращать «самый специфический суперкласс для всех значений ячеек в столбце». Судя по всему, вы можете возвращая любое количество типов классов для одного столбца, фактически нарушая контракт TableModel.

Как правило, типы столбцов являются статическими для данного набора данных таблицы, то есть класс для столбца не должен изменяться, пока не изменятся данные базовой таблицы. Я думаю, что важно спросить, зачем вам нужно возвращать такое конкретное значение.

В случае, если вы хотите визуализировать что-то конкретное для данного типа класса, вам лучше развернуть свой собственный TableCellRenderer и определить тип объекта для каждой ячейки. Оттуда вы можете сделать любой конкретный рендеринг по мере необходимости.

0 голосов
/ 06 декабря 2010

ResultSetMetaData НЕ предоставляет никакой информации о классе. Он предоставляет специфичные для базы данных типы данных, которые не отображаются автоматически на классы Java (например, «cidr» или «int8» в мире PostgreSQL), поэтому это предложение (кстати, не включало никакого исходного кода) на самом деле не помогает.

Кроме того, комментарий Джейсона Николса «Я думаю, что важно спросить, зачем вам нужно возвращать такое конкретное значение», показывает общую неосведомленность о том, как класс JTable используется в реальном мире.

Я бы хотел найти решение этой проблемы, когда у таблиц нулевые строки, где я все еще могу выяснить, что такое класс Java, который я должен использовать для визуализации своих ячеек для всего столбца. Идея о том, что выходные данные могут изменяться, основана на еще большей степени невежественности в отношении баз данных - тип данных столбца указывается в определении этого столбца, и независимо от того, какое его содержимое имеет тип данных, он не меняется в зависимости от того, какую строку вы используете. Смотрю это.

Конечно, одна из проблем с базами данных заключается в том, что определения столбцов могут разрешать или не разрешать значения NULL, и любой, кто подклассифицирует JTable для этого, должен понимать эту основную предпосылку и знать, как это проверять.

0 голосов
/ 04 февраля 2010

В дополнение к ответам на данный момент: при условии, что ваша модель поддерживается символом List (как было предложено в предыдущем вопросе), вы увидите IndexOutOfBoundsException, если попытаетесь отобразить ваш JTable, когда TableModel не содержит строк (т. е. List пусто). Это неприятный крайний случай (как я понимаю, вы пытаетесь визуализировать ResultSet - откуда вы знаете, что ResultSet не будет пустым?).

Чтобы избежать этого, почему вы не сделали то, что я предлагал изначально, и не определили класс каждого столбца из ResultSetMetaData?

0 голосов
/ 04 февраля 2010

Возможно:

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

Надеюсь, это поможет вам.

...