gpt4 book ai didi

java - 用大量行填充 JTable

转载 作者:行者123 更新时间:2023-11-29 09:48:41 25 4
gpt4 key购买 nike

我想在运行时用许多行(比如说 10000)填充一个 JTable。但是我所有的尝试都非常糟糕且效率低下。

起点是 addData 方法,它获取代表一行的对象列表。我试图通过 SwingWorker 填充表格,但这只适用于我的小数据。

另一种尝试是直接设置数据而不使用任何类型的线程,但这也非常慢,至少 UI 不会像 SwingWorker 那样被阻塞。

那么一般是怎么做到的呢?表格应该逐行或逐 block 填充,但不是全部填充,同时垂直滚动条应该是可滚动的。

我的表格模型:

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 定期 hibernate 或让步,以便有时间发布结果。

因此,在此示例中,我添加了 1、000、000 行。在我的测试中,它花费了不到 1 秒的时间......

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;

public class TestTableLoad01 {

public static void main(String[] args) {
new TestTableLoad01();
}

public TestTableLoad01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

MyTableModel model = new MyTableModel();
JTable table = new JTable(model);
table.setDefaultRenderer(Date.class, new TimeCellRenderer());

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

TableSwingWorker worker = new TableSwingWorker(model);
worker.execute();

}
});
}

public class TimeCellRenderer extends DefaultTableCellRenderer {

private DateFormat df;

public TimeCellRenderer() {
df = new SimpleDateFormat("HH:mm:ss");
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

if (value instanceof Date) {

value = df.format(value);

}

super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

return this;

}

}

public class MyTableModel extends AbstractTableModel {

private String[] columnNames = new String[]{"Date", "Row"};
private List<RowData> data;

public MyTableModel() {
data = new ArrayList<>(25);
}

@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 0 ? Date.class : Integer.class;
}

@Override
public String getColumnName(int col) {
return columnNames[col];
}

@Override
public int getColumnCount() {
return columnNames.length;
}

@Override
public int getRowCount() {
return data.size();
}

@Override
public Object getValueAt(int row, int col) {
RowData value = data.get(row);
return col == 0 ? value.getDate() : value.getRow();
}

public void addRow(RowData value) {
int rowCount = getRowCount();
data.add(value);
fireTableRowsInserted(rowCount, rowCount);
}

public void addRows(RowData... value) {
addRows(Arrays.asList(value));
}

private void addRows(List<RowData> rows) {
int rowCount = getRowCount();
data.addAll(rows);
fireTableRowsInserted(rowCount, getRowCount() - 1);
}
}

public class RowData {

private Date date;
private int row;

public RowData(int row) {
this.date = new Date();
this.row = row;
}

public Date getDate() {
return date;
}

public int getRow() {
return row;
}
}

public class TableSwingWorker extends SwingWorker<MyTableModel, RowData> {

private final MyTableModel tableModel;

public TableSwingWorker(MyTableModel tableModel) {
this.tableModel = tableModel;
}

@Override
protected MyTableModel doInBackground() throws Exception {

// This is a deliberate pause to allow the UI time to render
Thread.sleep(2000);

System.out.println("Start polulating");

for (int index = 0; index < 1000000; index++) {

RowData data = new RowData(index);
publish(data);

Thread.yield();

}

return tableModel;
}

@Override
protected void process(List<RowData> chunks) {
System.out.println("Adding " + chunks.size() + " rows");
tableModel.addRows(chunks);
}
}
}

关于java - 用大量行填充 JTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17414109/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com