JAVA - Странная проблема (возможно, проблема с потоками) с JTable & Model - PullRequest
3 голосов
/ 16 июня 2010

Я использую 2 таблицы (JTable) с их DefaultTableModels. Первая таблица уже заполнена. Вторая таблица заполняется для каждой строки первой таблицы (с использованием SQL-запроса). Моя цель - экспортировать каждую строку первой таблицы с соответствующими строками второй в файле Excel.

Я делаю это с помощью for (для каждой строки 1-й таблицы), в котором я записываю строку 1-й таблицы в файле Excel, а затем заполняю 2-ю таблицу (для этой строки 1-й таблицы). получить каждую строку из таблицы (фактически из ее модели) и поместить ее в файл Excel под текущей строкой 1-й таблицы. Это означает, что если в первой таблице будет n строк, я очистлю и снова заполню вторую таблицу n раз.

Весь этот код вызывается в отдельном потоке.

ПРОБЛЕМА Все работает отлично, за исключением того, что я получаю некоторые исключения. Странно то, что я не получаю ничего ложного в своем результате. Файл Excel идеален.

Некоторые строки исключений:

Исключение в потоке "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0> = 0 на java.util.Vector.elementAt (Vector.java:427) в javax.swing.table.DefaultTableModel.getValueAt (DefaultTableModel.java:632) в javax.swing.JComponent.paint (JComponent.java:1017) в javax.swing.RepaintManager.paint (RepaintManager.java:1220) в javax.swing.RepaintManager.paintDirtyRegions (RepaintManager.java:803)

Я предполагаю, что проблема заключается в том, что второй таблице необходимо заполнить еще некоторое время, прежде чем я попытаюсь получить из нее какие-либо данные. Вот почему я вижу RepaintManager и paintDirtyRegions в моих исключениях. Я также выполнил свою программу в режиме отладки и ставил точку останова после каждой совокупности 2-й таблицы. Затем я нажал F5, чтобы продолжить для каждой популяции 2-й таблицы, и исключений не появилось. Программа подошла к концу без каких-либо исключений. Это еще один важный факт, который говорит мне, что, возможно, в этом случае я дал таблице достаточно времени для заполнения.

Конечно, вы спросите меня:

  • Если ваша программа работает нормально, почему вас волнуют исключения? Я забочусь о том, чтобы избежать каких-либо проблем в будущем, и я хочу лучше понять Java и Java GUI и потоки.

  • Почему вы зависите от компонента графического интерфейса (и его модели) для получения информации и почему вы не воссоздаете набор результатов, который заполняет ваши таблицы с помощью SQL-запроса, и не получаете информацию из набора результатов? Это было бы лучшим и правильным способом. Дело в том, что у меня есть готовый код таблиц, и мне было проще получить информацию от них. Но правильным способом было бы получить все напрямую из базы данных. В любом случае, то, что я сделал, подняло мой вопрос, и ответ на него помог бы мне понять больше вещей о Java. Так я и запостил.

Ответы [ 2 ]

2 голосов
/ 16 июня 2010

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

Передача такой обработки вызовов из порожденного фонового / рабочего потока может выполняться через SwingUtilities.invokeLater () или SwingUtilities.invokeAndWait () .

Существует также определенное обсуждение как JTable, так и любой TableModel, которая была присоединена к его экземпляру в Сводная информация о пакете javax.swing javadocs .Кроме того, он не является поточно-ориентированным, поэтому любые вызовы, обращающиеся к данным из них, должны выполняться в потоке диспетчеризации событий.

Это наиболее вероятная причина возникновения исключений, с которыми вы сталкиваетесь, и различного поведения, с которым вы сталкиваетесь при выполнении.в отладчике это классический признак состояния гонки.Также нет надежного способа обойти это путем введения собственных блокировок и т. Д. Такие практики неизменно приводят к проблемам (таким как взаимоблокировки с блокировкой очереди отправки событий глубоко внутри библиотеки Swing) в долгосрочной перспективе, поскольку Swing действительно был действительноне предназначен для работы с потоками.

1 голос
/ 16 июня 2010

Исключение происходит, потому что одна из моделей таблиц возвращает значение null для вызова getValueAt (int row, int column).Причиной этого, вероятно, является внутренняя проблема в колебании или модели данных из-за того, что вы используете вторичный поток для доступа к моделям данных.В частности, в Swing API указано, что вы не можете использовать вторичную нить так, как вы описали.

В следующей статье приводятся дополнительные сведения о правиле с одной нитью в Swing.

http://java.sun.com/products/jfc/tsc/articles/threads/threads3.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...