排序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<DefaultTableModel> 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<DefaultTableModel>(model);
        ArrayList<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
        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<Void, Void> worker = new SwingWorker<Void, Void>(){
                    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"中的异常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)java.awt.EventQueue.dispatchEventImpl (EventQueue.java: 705)java.awt.EventQueue.access 000美元(EventQueue.java: 101)在java.awt.EventQueue 3.美元运行(EventQueue.java: 666)在java.awt.EventQueue 3.美元运行(EventQueue.java: 664)在java.security.AccessController。doPrivileged(本地方法)java.security.ProtectionDomain dointersectionprivilege 1.美元(ProtectionDomain.java: 76)java.awt.EventQueue.dispatchEvent (EventQueue.java: 675)java.awt.EventDispatchThread.pumpOneEventForFilters (EventDispatchThread.java: 211)java.awt.EventDispatchThread.pumpEventsForFilter (EventDispatchThread.java: 128)java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java: 117)java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java: 113)java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java: 105)java.awt.EventDispatchThread.run (EventDispatchThread.java: 90)线程"AWT-EventQueue-0"中的异常…

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

既然你使用的是SwingWorker,你应该尝试完全正确地使用它,例如使用它的publish API来调用model.addRow()

相关内容