Hallo zusammen,
bei meinem Problem handelt es sich um eine Client-Server Multiuser Architektur. Zu Jeder Zeit soll ein User in der Lage sein eine neue Zeile in seiner Table-View (JTable) anzulegen. Der Server wird darüber informiert und sendet eine Nachricht an alle Clients, so dass diese ihre TableViews entsprechend aktualisieren können. Soweit funktioniert alles wunderbar, außer wenn ein User sich gerade im EditModus der Table befindet, während er ein solches UpdateEvent erhält.
Wenn die neue Zeile oberhalb der gerade zu editierenden Zelle des Users liegt, werden natürlich alle darauf folgenden Zeilen eine Zeilennummer tiefer gesetzt. Da der TableCellEditor darauf nicht reagiert, bleibt der Edit-Modus der Zelle erhalten und somit wird nun der falsche Datensatz editiert.
Ich habe mal ein kleines Beispiel vorbereitet um das Problem etwas zu veranschaulichen:
Um die eingehenden Data-Events zu faken habe ich einfach einen Thread erzeugt, der alle 5 Sekunden eine neue Zeile an der Position 1 einfügt. Hoffe damit wird deutlich, was das Problem ist.
Habt ihr vielleicht irgendwelche Ideen, wie man damit umgehen kann? Sollte ich vielleicht die UpdateEvents des jeweiligen Clients cachen, solange sich dieser im EditModus befindet und im Anschluss ausführen? Doch was mache ich dann, wenn der User vielleicht sogar unbeabsichtigt 5 Minuten im Edit-Modus verharrt, weil er eine Zelle, welche viele Informationen benötigt ausfüllen muss? Im Anschluss alle Events auszuführen, könnte nicht ganz einfach sein zumal er dann längere Zeit eine veraltete Sicht auf die Daten besitzt. Habt ihr vielleicht noch andere Ideen das Problem zu umgehen? Leider kann ich die neuen Zeilen nicht einfach immer unten anlegen, da die Reihenfolge der Zeilen wichtig ist.
Vielen Dank im Vorraus.
Grüße,
ymene
bei meinem Problem handelt es sich um eine Client-Server Multiuser Architektur. Zu Jeder Zeit soll ein User in der Lage sein eine neue Zeile in seiner Table-View (JTable) anzulegen. Der Server wird darüber informiert und sendet eine Nachricht an alle Clients, so dass diese ihre TableViews entsprechend aktualisieren können. Soweit funktioniert alles wunderbar, außer wenn ein User sich gerade im EditModus der Table befindet, während er ein solches UpdateEvent erhält.
Wenn die neue Zeile oberhalb der gerade zu editierenden Zelle des Users liegt, werden natürlich alle darauf folgenden Zeilen eine Zeilennummer tiefer gesetzt. Da der TableCellEditor darauf nicht reagiert, bleibt der Edit-Modus der Zelle erhalten und somit wird nun der falsche Datensatz editiert.
Ich habe mal ein kleines Beispiel vorbereitet um das Problem etwas zu veranschaulichen:
Java:
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();
}
}
Um die eingehenden Data-Events zu faken habe ich einfach einen Thread erzeugt, der alle 5 Sekunden eine neue Zeile an der Position 1 einfügt. Hoffe damit wird deutlich, was das Problem ist.
Habt ihr vielleicht irgendwelche Ideen, wie man damit umgehen kann? Sollte ich vielleicht die UpdateEvents des jeweiligen Clients cachen, solange sich dieser im EditModus befindet und im Anschluss ausführen? Doch was mache ich dann, wenn der User vielleicht sogar unbeabsichtigt 5 Minuten im Edit-Modus verharrt, weil er eine Zelle, welche viele Informationen benötigt ausfüllen muss? Im Anschluss alle Events auszuführen, könnte nicht ganz einfach sein zumal er dann längere Zeit eine veraltete Sicht auf die Daten besitzt. Habt ihr vielleicht noch andere Ideen das Problem zu umgehen? Leider kann ich die neuen Zeilen nicht einfach immer unten anlegen, da die Reihenfolge der Zeilen wichtig ist.
Vielen Dank im Vorraus.
Grüße,
ymene
Zuletzt bearbeitet von einem Moderator: