正如标题所说,当我向基础列表中添加内容时,会将空单元格添加到我的表中。
主类:
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MainFrame frame = new MainFrame();
}
});
}
}
MainFrame类:
import java.awt.BorderLayout;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JTable;
public class MainFrame extends JFrame {
private JTable table;
private ArrayList<String> strings;
public MainFrame() {
setTitle("Stack Overflow");
setSize(800, 800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
setVisible(true);
strings = new ArrayList<String>();
table = new JTable(new TableModel(strings));
add(table,BorderLayout.CENTER);
for (int i = 0; i < 10; i++) {
strings.add("data");
}
}
}
AbstractTableModel类:
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class TableModel extends AbstractTableModel {
private String[] colNames = {"Col1","Col2"};
private List<String> strings;
public TableModel(List<String> strings) {
this.strings = strings;
}
@Override
public String getColumnName(int column) {
return colNames[column];
}
@Override
public int getRowCount() {
return strings.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getValueAt(int rowIndex, int columnIndex) {
if (rowIndex*2 + columnIndex >= strings.size()) return "";
return strings.get(rowIndex*2 + columnIndex);
}
}
是否有更好的方法来从我的1D数组中获取项目,以便从左到右,从上到下(没有多余的空单元格)填充表格?
为什么仍然会发生此问题?
strings.add("data");
您应该使用类似:
strings.add("data" + i);
所以每个单元格中的值都不同。这样,您可以判断数据是否正确显示。
只要将内容添加到列表,该列表就会使用fireTableDataChanged()动态更新。
错了。 fireTableDataChanged()方法只能由TableModel内部的方法调用。一旦创建了TableModel,您就不用理会ArrayList并在TableModel上调用一个方法来更新ArrayList。
因此您需要在TableModel中添加类似addItem(…)
的方法。然后,TableModel将更新ArrayList,如果项数为奇数,则调用fireTableRowsInserted(…)
,如果项数为偶数,则调用fireTableRowsUpdated(…)
。
类似:
public void addItem(String item)
{
strings.add( item );
if (string.size() % 2 == 0)
fireTableRowsUpdated(…);
else
fireTableRowsInserted(…);
}
您拥有的数据和建模方式是两个不同的问题,不要害怕将它们分开来实现您的目标,例如:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.table.AbstractTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTable table;
private SequentialTableModel model;
public TestPane() {
setLayout(new BorderLayout());
model = new SequentialTableModel();
table = new JTable(model);
add(new JScrollPane(table));
Timer timer = new Timer(500, new ActionListener() {
private int count = 0;
@Override
public void actionPerformed(ActionEvent e) {
model.add("Data " + (++count));
}
});
timer.start();
}
}
public class SequentialTableModel extends AbstractTableModel {
private String[] colNames = {"Col1", "Col2"};
private List<List<String>> rows = new ArrayList<>(32);
public SequentialTableModel() {
}
@Override
public String getColumnName(int column) {
return colNames[column];
}
@Override
public int getRowCount() {
return rows.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getValueAt(int rowIndex, int columnIndex) {
List<String> values = rows.get(rowIndex);
if (columnIndex >= values.size()) {
return null;
}
return values.get(columnIndex);
}
public void add(String value) {
if (rows.isEmpty()) {
addNewRow(value);
return;
}
List<String> lastRow = rows.get(rows.size() - 1);
if (lastRow.size() < 2) {
lastRow.add(value);
fireTableCellUpdated(rows.size() - 1, lastRow.size() - 1);
} else {
addNewRow(value);
}
}
protected void addNewRow(String value) {
List<String> row = new ArrayList<>(2);
row.add(value);
rows.add(row);
fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
return;
}
}
}