如何在编辑行时处理JTable的传入数据?

时间:2010-12-14 17:21:43

标签: java jtable edit multi-user

想象一下,我们有一个客户端/服务器多用户架构。用户可以随时在其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();
  }
}

为了伪造传入的Data-Events,我使用了一个线程,它每5秒在位置1上添加一个新行。足以说明问题所在。

您对如何处理这个有什么建议吗?只要表被编辑并且之后执行updateEvents,我是否应该禁止updateEvents?但是,当用户在编辑模式下停留5分钟时,我该怎么办?排除所有更新 - 他错过的事件可能会有点痛苦。你可能还有其他想法吗?

提前谢谢! ymene

2 个答案:

答案 0 :(得分:2)

您是否考虑过将正在编辑的单元格设置为正确的单元格?在您的示例中,它非常简单,因为您始终在0处添加新单元格。

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

对于发生任意插入的情况(不是在第0行),如果插入的行高于或低于当前正在编辑的行,则必须添加一个检查

答案 1 :(得分:0)

我建议你使用SwingWorker!

它可以在EDT之外做一些工作,然后当其他用户添加行时,你的JTable会实时更新!

祝你好运