1

クライアント/サーバーのマルチユーザー アーキテクチャがあるとします。ユーザーはいつでも自分の 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 分間ほど編集モードにとどまっている場合、どうすればよいでしょうか? 彼が逃したすべての更新イベントを実行すると、少し苦痛になる可能性があります。他のアイデアはありますか?

前もって感謝します!イメネ

4

2 に答える 2

2

編集中のセルを正しいセルに設定することを検討しましたか? あなたの例では、常に新しいセルを 0 に追加しているので、かなり簡単です。

while ( true ) {
        Thread.sleep( 5000 );
        table.setEditingRow(table.getEditingRow() + 1);
        ((StandardTableModel) table.getModel()).addRow( new Data( 4, "Vier" ), 0 ); }

任意の挿入が (行 0 ではなく) 行われている場合、挿入される行が現在編集中の行の上または下にあるかどうかのチェックを追加する必要があります。

于 2011-01-04T12:03:10.523 に答える
0

SwingWorker を使用することをお勧めします!

EDT の外部でいくつかの作業を行うことができ、他のユーザーが行を追加すると、JTable がリアルタイムで更新されます。

よろしくお願いします

于 2010-12-22T11:48:06.093 に答える