首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为自定义JTable TableModel创建addRows()方法

为自定义JTable TableModel创建addRows()方法
EN

Stack Overflow用户
提问于 2012-05-13 17:05:00
回答 1查看 2.2K关注 0票数 1

我在下面的解释是漫无边际的,沸腾下来,有没有一种方法可以在不触发事件的情况下添加一个Row,这样我就可以添加多个行并触发一个事件来一次更新所有这些行?而不必添加代码来包含自定义模型中的表数据?

我有一个从DefaultTableModel扩展而来的自定义TableModel,这样我就可以使用DefaultTableModel为我跟踪数据,同时仍然拥有我自己的一些自定义方法。

问题是,当我想要添加多行时,我想使用"addRows(String val)“方法可能会更快。然后,我可以触发一个事件(可能是fireTableDataChanged() )来一次性更新所有行。例如,我当前的方法:

代码语言:javascript
代码运行次数:0
运行
复制
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>});

然后,我会根据需要多次重复上面的内容。问题是,每一个都会触发一个单独的事件。如果我可以使用我的定制表模型来做这件事,(我想)会快得多:

代码语言:javascript
代码运行次数:0
运行
复制
JTable table1 = new JTable(new dgvTableModel(new String[] {<values>},0, new String[] {<values>}));
table1.addRows(new String[][] {{<values1 here}, {values2 here}, . . .}});

然后在表格模型中:

代码语言:javascript
代码运行次数:0
运行
复制
public void addRows(String[][] values) {
   for (String[] vals : values)           
       super.addRow(vals);
   }
   fireTableDataChanged();
}

我可以很容易地对此进行编码。问题再次出现,"super.addRow(vals);“行将在每次通过时触发一个事件。有没有一种方法可以在不添加代码的情况下让我的模型包含表数据本身,从而防止每次我添加一行时都触发该事件?以便它等待addRows方法中的fireTableDataChanged()调用?

作为参考,我的定制表模型的代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
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();
}
}

当然,激发一个事件来显示每一行,比为每行激发一个事件更快?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-13 17:59:27

'AbstractTableModel.fireTableDataChanged()‘用于向模型(以及由模型通知的JTable UI )指示表中所有可能的数据可能已经更改,需要检查。这可能(重点是可能)是一个昂贵的操作。如果您知道添加了哪些行,只需使用'AbstractTableModel.fireTableRowsInserted(int firstRow,int lastRow)‘方法。这将确保只有效果行被视为已更改。看看AbstractTableModel中的所有fire*方法。你真的可以对哪些行、单元格等进行细粒度的控制。

再说一次,你所做的可能是过早的优化。除非您的JTable中有五万条记录,否则这可能不会引起注意。但是,如果您的JTable中有大量记录,那么您最好还是懒惰地加载它们。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10570531

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档