下面我的解释是rambles,煮沸,有没有一种方法可以添加一行而不触发一个事件,这样我就可以添加多行并触发一个事件来立即更新所有这些行?无需添加代码以包含自定义模型中的表数据?
我有一个自定义的TableModel,它从DefaultTableModel扩展,以便我可以使用DefaultTableModel来跟踪我的数据,同时还有我自己的一些自定义方法。
问题是,当我希望添加多行时,我认为拥有“addRows(String [] [] val)”方法可能会更快。然后我可以触发一个事件,可能是fireTableDataChanged()来一次更新所有行。例如,我目前的方法:
JTable table1 = new JTable(new dgvTableModel(new String[] {<values>},0, new String[] {<values>}));
table1.addRow(new String[] {<values here>});
table1.addRow(new String[] {<values here>});
table1.addRow(new String[] {<values here>});
然后我会根据需要多次重复上述内容。问题是,每一个都将触发一个单独的事件。如果我可以使用我的自定义表模型执行此操作,那会快得多(我认为):
JTable table1 = new JTable(new dgvTableModel(new String[] {<values>},0, new String[] {<values>}));
table1.addRows(new String[][] {{<values1 here}, {values2 here}, . . .}});
然后在表格模型中:
public void addRows(String[][] values) {
for (String[] vals : values)
super.addRow(vals);
}
fireTableDataChanged();
}
我可以轻松编写代码。问题是“super.addRow(vals);” line每次都会触发一个事件。有没有办法在不添加代码让我的模型包含表数据本身的情况下,以防止每次添加行时触发该事件?这样它等待addRows方法中的fireTableDataChanged()调用?
供参考,我的自定义表模型的代码:
import java.awt.Color;
import java.util.ArrayList;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
public class dgvTableModel extends DefaultTableModel {
//private DataTable tableVals = new DataTable();
private ArrayList<Color> rowColors;
//private ArrayList<Object[]> data = new ArrayList<>();
//default constructor has no data to begin with.
private int[] editableColumnNames;
public dgvTableModel(String[] colNames, int rowCount)
{
super(colNames, rowCount);
}
public dgvTableModel(String[] colNames, int rowCount, String[] editableColNames)
{
super(colNames, rowCount);
//this.tableVals.setColNames(colNames);
if (editableColNames!=null && editableColNames.length >0)
{
editableColumnNames = new int[editableColNames.length];
int count = 0;
for (int i =0; i< editableColNames.length;i++)
{
for (String val : colNames)
{
if (val.equalsIgnoreCase(editableColNames[i]))
{
editableColumnNames[count] = i;
count+=1;
break;
}
}
}
}
}
public dgvTableModel(String[] colNames, int rowCount, String[] editableColNames, boolean colorChanges)
{
super(colNames, rowCount);
Color defColor = UIManager.getDefaults().getColor("Table.background");
if (editableColNames!=null && editableColNames.length >0)
{
editableColumnNames = new int[editableColNames.length];
int count = 0;
if (colorChanges)
{
rowColors = new ArrayList<>();
}
for (int i =0; i< colNames.length;i++)
{
if (colorChanges)
{
rowColors.add(defColor);
}
for (String val : editableColNames)
{
if (val.equalsIgnoreCase(colNames[i]))
{
editableColumnNames[count] = i;
count+=1;
break;
}
}
}
}
else if (colorChanges)
{
rowColors = new ArrayList<>();
for (String val : colNames)
{
rowColors.add(defColor);
}
}
}
@Override
public boolean isCellEditable(int row, int column)
{
if(editableColumnNames!=null && editableColumnNames.length >0)
{
for (int colID : editableColumnNames)
{
if (column==colID)
return true;
}
}
return false;
}
public void setRowColor(int row, Color c)
{
rowColors.set(row, c);
fireTableRowsUpdated(row,row);
}
public Color getRowColor(int row)
{
return rowColors.get(row);
}
@Override
public Class getColumnClass(int column)
{
return String.class;
}
@Override
public String getValueAt(int row, int column)
{
return super.getValueAt(row, column).toString();
}
}
肯定会触发一个事件来显示每一行,比为每一行触发一个事件要快吗?
答案 0 :(得分:2)
'AbstractTableModel.fireTableDataChanged()'用于指示模型(以及模型通知的JTable UI)表中的所有可能数据可能已更改并需要进行检查。这可以(强调可以)是昂贵的操作。如果您知道添加了哪些行,则只需使用'AbstractTableModel.fireTableRowsInserted(int firstRow,int lastRow)'方法。这将确保仅将效果行视为已更改。看看AbstractTableModel中的所有fire *方法。你真的可以对哪些行,单元格等看起来很脏进行精细控制。
然后你的做法可能是过早优化。除非你的JTable中有五十万条记录,否则这可能不会是明显的。但是如果你的JTable中有大量的记录,你可能会懒得加载它们。