Imaginons que nous ayons une architecture multi-utilisateur client/serveur. A tout moment, un utilisateur peut ajouter un nouveau TableRow dans son JTable. Le serveur est informé et envoie un message à tous les clients, de sorte que leurs données (c'est-à-dire leurs vues de table) sont également mises à jour. Cela fonctionne parfaitement, sauf si un utilisateur modifie actuellement une ligne dans cette table, tout en devenant un updateEvent. Lorsque la nouvelle tableRow est au-dessus de la ligne actuellement éditée par l'utilisateur, la cellule respective change également, mais la tableEditor ne le remarque pas et donc la mauvaise rangée est éditée et modifiée maintenant.Comment gérer les données entrantes pour JTable lors de la modification d'une ligne?
J'ai créé un petit exemple pour briser ce problème à quelques lignes de code, il pourrait être plus facile de me suivre:
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();
}
}
Pour simuler les données-événements entrants j'ai utilisé un fil, ce qui ajoute une nouvelle rangée sur la position 1 toutes les 5 secondes. Assez bon pour montrer quel est le problème.
Avez-vous des suggestions pour gérer cela? Devrais-je refuser updateEvents tant que la table est éditée et exécuter les updateEvents après? Mais que vais-je faire, quand l'utilisateur reste en mode édition pendant 5 minutes? Executer toutes les mises à jour - Les événements qu'il a manqués pourraient devenir un peu douloureux. Avez-vous d'autres idées?
Merci d'avance! ymene
Je ne peux pas croire que c'est simple comme ça. Merci beaucoup, cette solution va me sauver beaucoup de solutions de contournement! Malheureusement, je ne peux pas vous récompenser encore. Il dit que je dois attendre encore 19 heures. Mais je ne l'oublierai pas! – crusam
Pas de soucis. Heureux que ça a marché pour toi :) –