Sorting JTable causes NullPointerException
I have a JTable which, when the appropriate button is clicked, begins to fill with the results of a file tree walk that goes on in the background. This works fine.
I then decided I want the table to be sorted. After some reading I created a TableRowSorter and set the table to use it. It appeared to work, but upon closer inspection I noticed several of the file results were absent. I disabled the sorter and ran the program again and all of the files were present, upon re-enabling the sorter again some were missed, but it seemed to be different files each time that were being dropped.
To examine this I created a self-contained block of code as a test (see below), which was to be representative of the JTable code (In fact, large chunks were lifted directly from the existing program code). The file tree walk is represented by a for loop. Again, it worked perfectly without the sorter. When I enabled the sorter, however, (by uncommenting line 29) the entire progr开发者_开发技巧am frozeand I was told there was a NullPointerException.
I have no Idea what is causing either of these problems, nor if they are, in fact, even related. Any ideas on what is wrong are welcome.
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();
}
});
}
}
Stacktrace
This is part of the stack trace, it repeats..
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at javax.swing.DefaultRowSorter.convertRowIndexToModel(DefaultRowSorter.java:518) at javax.swing.JTable.convertRowIndexToModel(JTable.java:2645) at javax.swing.JTable.getValueAt(JTable.java:2720) at javax.swing.JTable.prepareRenderer(JTable.java:5718) at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114) at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016) at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812) at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161) at javax.swing.JComponent.paintComponent(JComponent.java:778) at javax.swing.JComponent.paint(JComponent.java:1054) at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221) at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295) at javax.swing.RepaintManager.paint(RepaintManager.java:1206) at javax.swing.JComponent._paintImmediately(JComponent.java:5169) at javax.swing.JComponent.paintImmediately(JComponent.java:4980) at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:770) at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728) at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677) at javax.swing.RepaintManager.access$700(RepaintManager.java:59) at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1621) at 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) at 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) Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException ...
Your code has a big problem that may explain what you observe: you are modifying your table model outside the EDT, which is evil.
Since you are using a SwingWorker
, you should try to use it completely correctly, e.g. use its publish
API to call model.addRow()
.
精彩评论