【发布时间】:2013-06-29 03:26:04
【问题描述】:
我想在运行时用很多行(比如说 10000)填充一个 JTable。但是我所有的尝试都非常糟糕和低效。
起点是addData 方法,它获取代表一行的对象列表。我试图通过 SwingWorker 填充表格,但这仅适用于我的小数据。
另一个尝试是直接设置数据而不使用任何类型的线程,但这也很慢,至少 UI 不会像 SwingWorker 那样被阻塞。
那么一般情况下你是怎么做的呢?表格应逐行或逐块填充,但不能全部填充,同时垂直滚动条应可滚动。
我的表模型:
public class MyTableModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = 1L;
String[] columnNames;
public Map<Long, ErrorMessage> data = new LinkedHashMap<Long, ErrorMessage>();
public MyTableModel(String[] header) {
columnNames = header;
}
public String getColumnName(int col) {
return columnNames[col].toString();
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public Object getValueAt(int row, int col) {
.
.
return value;
}
public void addRow(long id, MyDataObject o) {
data.put(id, m);
fireTableRowsInserted(0,nqm_messages.size()-1);
}
}
SwingWorker 实现:
class TableSwingWorker extends SwingWorker<MyTableModel, MyDataObject> {
private final MyTableModel tableModel;
List<MyDataObject> messages;
public TableSwingWorker(MyTableModel tableModel, List<MyDataObject> dataList) {
this.tableModel = tableModel;
this.messages = new LinkedList<MyDataObject>(mm);
}
@Override
protected MyTableModel doInBackground() throws Exception {
for(MyDataObject s : messages) {
publish(s);
}
return tableModel;
}
@Override
protected void process(List<MyDataObject> chunks) {
for(MyDataObject row : chunks){
Long l = Long.parseLong(row.getId());
tableModel.addRow(l, row);
}
}
}
将对象添加到 JTable:
public void addData(List<MyDataObject> o) {
MyTableModel m = (MyTableModel)table.getModel();
(new TableSwingWorker(m,o)).execute();
//for(int i=0; i < mm.size();i++) {
// long l = Long.parseLong(mm.get(i).getId());
// m.addRow(l, mm.get(i));
//}
}
【问题讨论】:
-
最好的方法,恕我直言,不要这样做。没有人能够对这么多行做任何事情。添加搜索表单。添加分页。
-
你的
SwingWorker的问题是它阻塞了。这意味着在主循环之后(或接近结束)之前,它永远不会有时间publish结果。有两件事来找。 1- 在主循环中添加一个小的延迟(5-10 毫秒),这将允许SwingWorker和处理所有已发布结果的机会 2- 向您的表模型添加一个批处理添加,这将允许您在其中添加多行单个方法调用 -
为什么要触发一个事件,表明所有行都已插入到您的
addRow方法中?
标签: java swing jtable swingworker