想象一下,我们有一个客户端/服务器多用户架构。用户可以随时在其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
答案 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会实时更新!
祝你好运