1

以下の私の説明は、要約すると、イベントを発生させずに行を追加して、複数の行を追加し、イベントを発生させてそれらすべてを一度に更新できるようにする方法はありますか? カスタム モデルにテーブル データを含めるコードを追加する必要はありませんか?

私は DefaultTableModel から拡張されたカスタム TableModel を持っているので、DefaultTableModel を使用してデータを追跡できますが、独自のカスタム メソッドもいくつかあります。

問題は、複数の行を追加したい場合、「addRows(String[][] val)」メソッドを使用する方が速いと考えていたことです。その後、1 つのイベント (おそらく 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);」ということです。行は毎回イベントを発生させます。モデルにテーブルデータ自体を含めるコードを追加せずに、行を追加するたびにそのイベントが発生しないようにする方法はありますか? 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();
}
}

すべての行を表示するために 1 つのイベントを確実に発生させることは、行ごとに 1 つのイベントを発生させるよりも高速ですか?

4

1 に答える 1

2

「AbstractTableModel.fireTableDataChanged()」は、モデル (およびモデルによって通知される JTable UI) に、テーブル内のすべての可能なデータが変更された可能性があり、チェックする必要があることを示すために使用されます。これは (can に重点を置いて) 高価な操作になる可能性があります。追加された行がわかっている場合は、代わりに「AbstractTableModel.fireTableRowsInserted(int firstRow, int lastRow)」メソッドを使用してください。これにより、効果行のみが変更されたように見えるようになります。AbstractTableModelのすべての fire* メソッドを見てください。どの行、セルなどをダーティと見なすかを細かく制御できます。

次に、あなたがしていることは時期尚早の最適化かもしれません。JTable に 5 万件のレコードがない限り、これはおそらく気にならないでしょう。しかし、JTable に大量のレコードがある場合は、とにかくそれらを遅延ロードした方がよいかもしれません。

于 2012-05-13T09:59:27.290 に答える