Это был бы мой первый вопрос в StackOverflow, но, конечно, не первый раз это было полезно. Однако я не стал больше пытаться найти различные возможные решения, которые я нашел до сих пор.java.lang.NullPointerException при быстром обновлении JList
В настоящее время я выполняю стажировку и создаю утилиту для визуализации информации, считываемой через интерфейс USB-to-CAN - «сеть контроллеров». Проще говоря: он считывает сообщения с CAN-разъема на встроенной системе. Каждое сообщение состоит из поля идентификатора (содержащего адрес источника, адрес назначения, идентификатор и т. Д.) + 8 максимальных байтов данных. Эти поля преобразуются в строки, и я хочу добавлять их в JList каждый раз при получении нового сообщения. JList 'log_listview' инициализируется новой версией DefaultListModel 'listModel', и она добавляется в Can_Panel, ContentPane. Чтение происходит в отдельном потоке с именем «vci_thread», который инициализируется и запускается сразу после создания панели.
Чтение начинается только через 5 секунд, время, необходимое для инициализации интерфейса USB-to-CAN. На первый взгляд, JList хорошо работает. Каждое полученное сообщение правильно добавлено в listModel, и я даже не заметил, что были ошибки, потому что программа просто продолжается без отсутствующих элементов, автоматической прокрутки и автоматического удаления первого элемента, когда listModel.size()> 99 ...
Теперь и тогда я получаю следующее сообщение об ошибке («Размер: #» является отладочный вывод фактического числа элементов в JList):
Size: 60
Size: 61
Size: 62
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.BufferStrategyPaintManager.flushAccumulatedRegion(Unknown Source)
at javax.swing.BufferStrategyPaintManager.endPaint(Unknown Source)
at javax.swing.RepaintManager.endPaint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1000(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Size: 63
Size: 64
Size: 65
Size: 66
Кроме того, когда много сообщений приходят быстро, я регулярно получаю следующую ошибку. Я считаю, что это что-то делать с удалением первого индекса, так как размер в настоящее время 100:
Size: 100
Size: 100
Size: 100
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 99 >= 99
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1000(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Size: 100
Size: 100
Вот код, который выполняется после того, как новое сообщение CAN считывается и байты были преобразованы в строки :
// Add a new element containing the strings:
listModel.addElement(counter + ": " + src_addr_hex + " " + dest_addr_hex + " - " + predef_hex + " - " + str_data);
// Auto scroll down after the element has been added
if (listModel.size()-1 >= 0) {
try {
log_listview.ensureIndexIsVisible(listModel.size()-1);
} catch (Exception ex) {
//
}
}
// When listModel contains 100 elements, remove the first index
if (listModel.size()>99) {
listModel.remove(0);
}
Это показание, вместе с этим код выполняется внутри, а() петли и включает в себя Thread.sleep (1) каждый раз, чтобы ограничить использование центрального процессора. Я убедил с try {} catch(), что, когда нет нового сообщения для чтения, преобразование строки и добавление в JList просто пропущены. Когда сообщения поступают быстрее, чем один цикл этого цикла, они просто кэшируются и обрабатываются один за другим, пока в конце концов моя программа не догонит. Это довольно обширный вопрос, но я надеюсь, что он сможет мне помочь.
Обновление: Я переместил код в новый runnable 'update_JList' и назвал его методом SwingUtilities.invokeLater сразу после прочтения строки. Я не получаю никаких ошибок, и здорово видеть, насколько плавные обновления графического интерфейса. Тем не менее, в настоящее время я столкнулся с другой проблемой дубликатов или недостающие элементы в JList:
Слева находится отладочный вывод, показывающий каждое входящее сообщение по одному. Справа находится JList, отображающий сообщение с адресом источника 45 14 раз.
a) убедитесь, что обновление списка происходит на EDT. B) при условии, что обеспечение выполняется в listDataListener, убедитесь, что оно происходит _after_, список готов с любым внутренним обновлением, которое завершает ваш код в invokeLater – kleopatra
что-то неправильное в коде, который вы не показываете ... заметьте, мы не можем прочесть ваш код, по крайней мере, на расстоянии ;-) Показать SSCCE, который демонстрирует проблему – kleopatra
В настоящее время я не могу придумать SSCCE для тиражирования проблема, и я боюсь, что вам понадобится интерфейс USB-to-CAN и та же встроенная система для тестирования с помощью :) Проблема дубликатов, по-видимому, решена путем установки логического состояния после чтения нового сообщения CAN и сброса это сразу после добавления элемента. Только время от времени один элемент отсутствует по сравнению с выходом отладки, хотя между этими двумя строками нет кода: System.out.println («Строки»); & SwingUtilities.invokeLater (update_JList); –