对JTable进行排序会导致NullPointerException

我有一个JTable,当点击相应的按钮时,它开始填充在后台继续的文件树步行的结果。 这很好用。

然后我决定要对表进行排序。 经过一些阅读后,我创建了一个TableRowSorter并设置表来使用它。 它似乎工作,但仔细检查后,我注意到几个文件结果都没有。 我禁用了分拣机并再次运行程序并且所有文件都存在,再次重新启用分拣机时有些遗漏,但每次丢弃时似乎都是不同的文件。

为了检验这一点,我创建了一个自包含的代码块作为测试(见下文),它代表了JTable代码(事实上,大块直接从现有程序代码中提取)。 文件树遍历由for循环表示。 再次,它没有分拣机就完美地工作了。 然而,当我启用分拣机时(通过取消注释第29行)整个程序冻结,我被告知有一个NullPointerException。

我不知道造成这些问题的原因是什么,事实上它们甚至是相关的。 任何有关错误的想法都是受欢迎的。

import javax.swing.table.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; public class Sort extends JFrame{ private JTable table; private DefaultTableModel model; private TableRowSorter sorter; private JButton go; public Sort(){ super("Sort"); // Create table and model model = new DefaultTableModel(0, 4); table = new JTable(model); // Setup sorting sorter = new TableRowSorter(model); ArrayList sortKeys = new ArrayList(); sortKeys.add(new RowSorter.SortKey(2, SortOrder.ASCENDING)); sortKeys.add(new RowSorter.SortKey(3, SortOrder.ASCENDING)); sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING)); sorter.setSortKeys(sortKeys); //table.setRowSorter(sorter); // Create Scroll Pane JScrollPane tableScroller = new JScrollPane(table); table.setFillsViewportHeight(true); tableScroller.setPreferredSize(new Dimension(500, 200)); // Setup button go = new JButton("Go"); go.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ SwingWorker worker = new SwingWorker(){ public Void doInBackground(){ for(int i = 0; i < 200; i++){ model.addRow( new Object[] { (new Integer(i)), String.valueOf(i), String.valueOf(i%50), String.valueOf(i%10) } ); } return null; } }; worker.execute(); } }); // Assemble GUI JPanel panel = new JPanel(new BorderLayout()); panel.add(tableScroller, BorderLayout.CENTER); panel.add(go, BorderLayout.SOUTH); setContentPane(panel); setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String[] args){ SwingUtilities.invokeLater(new Runnable(){ public void run(){ new Sort(); } }); } } 

堆栈跟踪

这是堆栈跟踪的一部分,它重复..

线程“AWT-EventQueue-0”中的exceptionjava.lang.NullPointerException
    在javax.swing.DefaultRowSorter.convertRowIndexToModel(DefaultRowSorter.java:518)
    在javax.swing.JTable.convertRowIndexToModel(JTable.java:2645)
    在javax.swing.JTable.getValueAt(JTable.java:2720)
    在javax.swing.JTable.prepareRenderer(JTable.java:5718)
    在javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
    在javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
    在javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
    在javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
    在javax.swing.JComponent.paintComponent(JComponent.java:778)
    在javax.swing.JComponent.paint(JComponent.java:1054)
    在javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
    在javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295)
    在javax.swing.RepaintManager.paint(RepaintManager.java:1206)
    在javax.swing.JComponent._paintImmediately(JComponent.java:5169)
    在javax.swing.JComponent.paintImmediately(JComponent.java:4980)
    在javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:770)
    在javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728)
    在javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677)
    在javax.swing.RepaintManager.access $ 700(RepaintManager.java:59)
    在javax.swing.RepaintManager $ ProcessingRunnable.run(RepaintManager.java:1621)
    在java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
     at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
     at java.awt.EventQueue.access $ 000(EventQueue.java:101)
     at java.awt.EventQueue $ 3.run(EventQueue.java:666)
     at java.awt.EventQueue $ 3.run(EventQueue.java:664)
     at java.security.AccessController.doPrivileged(Native Method)
     at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76)
    在java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
     at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
     at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
     at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
     at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
线程“AWT-EventQueue-0”中的exceptionjava.lang.NullPointerException
     ...

你的代码有一个很大的问题, 可以解释你所观察到的:你正在EDT 之外修改你的表模型,这是邪恶的。

由于您使用的是SwingWorker ,因此应该尝试完全正确使用它,例如使用其publish API来调用model.addRow()