想象一下我们有一个客户端/服务器多用户架构。任何时候用户都可以在他的 JTable 中添加一个新的 TableRow。服务器收到通知并向所有客户端发送消息,因此他们的数据(意味着他们的表格视图)也得到更新。这工作得很好,除非用户当前正在编辑该表中的一行,同时成为一个更新事件。
当新的 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 分钟时,我该怎么办?执行他错过的所有更新事件可能会有点痛苦。您可能还有其他想法吗?
先感谢您!梅内