我有一个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()
。