クライアント/サーバーのマルチユーザー アーキテクチャがあるとします。ユーザーはいつでも自分の JTable に新しい TableRow を追加できます。サーバーは通知を受けてすべてのクライアントにメッセージを送信するため、クライアントのデータ (テーブルビューを意味する) も更新されます。ユーザーが現在そのテーブルの行を編集しているときに updateEvent になっている場合を除き、これは問題なく機能します。
新しい tableRow がユーザーから現在編集されている行の上にある場合、それぞれのセルも変更されますが、tableEditor はこれに気付かないため、間違った行が編集および変更されています。
この問題をいくつかのコード行に分割するための小さな例を作成したので、従うのが簡単かもしれません:
public class TableEventHandlingExample extends JPanel
{
static JFrame frame;
JTable table;
public TableEventHandlingExample()
{
table = new JTable( new StandardTableModel( createTestData() ) );
final Thread thread = new Thread( new Runnable()
{
@Override
public void run()
{
try
{
while ( true )
{
Thread.sleep( 5000 );
((StandardTableModel) table.getModel()).addRow( new Data( 4, "Vier" ), 0 );
}
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
}
} );
thread.start();
add( new JScrollPane( table ) );
}
private List<Data> createTestData()
{
Data data1 = new Data( 1, "Eins" );
Data data2 = new Data( 2, "Zwei" );
Data data3 = new Data( 3, "Drei" );
List<Data> dataList = new ArrayList<Data>();
dataList.add( data1 );
dataList.add( data2 );
dataList.add( data3 );
return dataList;
}
public static void main( String[] args )
{
frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setLayout( new BorderLayout() );
frame.setBounds( 400, 400, 500, 500 );
frame.add( new TableEventHandlingExample() );
frame.setVisible( true );
}
}
class StandardTableModel extends AbstractTableModel
{
List<Data> dataList;
public StandardTableModel( List<Data> dataList )
{
this.dataList = dataList;
}
@Override
public int getColumnCount()
{
return 2;
}
@Override
public int getRowCount()
{
return dataList.size();
}
@Override
public boolean isCellEditable( int rowIndex, int columnIndex )
{
return true;
}
@Override
public Class<?> getColumnClass( int columnIndex )
{
if ( columnIndex == 0 )
return Integer.class;
return String.class;
}
@Override
public Object getValueAt( int rowIndex, int columnIndex )
{
if ( columnIndex == 0 )
return dataList.get( rowIndex ).getId();
return dataList.get( rowIndex ).getName();
}
@Override
public void setValueAt( Object aValue, int rowIndex, int columnIndex )
{
Data data = dataList.get( rowIndex );
if ( columnIndex == 0 )
data.setId( (Integer) aValue );
else
data.setName( (String) aValue );
}
public void addRow( Data data, int index )
{
if ( index > dataList.size() )
{
return;
}
dataList.add( index, data );
fireTableRowsInserted( index, index );
}
}
class Data
{
private int id;
private String name;
public Data( int id, String name )
{
this.id = id;
this.name = name;
}
public int getId()
{
return id;
}
public void setId( int id )
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
@Override
public String toString()
{
return getName();
}
}
着信データ イベントを偽造するために、5 秒ごとに位置 1 に新しい行を追加するスレッドを使用しました。問題が何であるかを示すのに十分です。
これを処理する方法について何か提案はありますか? テーブルが編集され、後で updateEvents を実行する限り、updateEvents を禁止する必要がありますか? しかし、ユーザーが 5 分間ほど編集モードにとどまっている場合、どうすればよいでしょうか? 彼が逃したすべての更新イベントを実行すると、少し苦痛になる可能性があります。他のアイデアはありますか?
前もって感謝します!イメネ