Breve descrizione di un problema.Interagire con JTable che viene rapidamente aggiornato con nuove righe
Supponiamo di avere JTable e l'utente che interagiscono con esso in qualche modo. TableModel di questa tabella è in continua evoluzione. Come assicurarsi che quando l'utente tenta di ottenere alcune informazioni dalla tabella facendo riferimento a una colonna costante e alla riga attualmente selezionata (dal suo rowIndex ricevuto da JTable), non entrerà in situazione quando TableModel viene modificato e il suo rowIndex ottenuto da JTable è non corrisponde più allo stesso valore in TableModel.
seguito è domanda iniziale che spiega problema in modo più dettagliato:
Considerate seguente situazione:
C'è JTable che mostra informazioni utente sulle richieste attualmente in esecuzione in un qualche sistema
Quando una nuova richiesta entra nel sistema, viene aggiunta una nuova riga alla tabella
utente può interagire con la tabella facendo clic destro su un (modello di singola riga di selezione è utilizzato in tabella) di fila e l'opzione scegliendo dal menu (come: annullare, rinviare, riprovare, ecc)
v'è separata classe che implementa l'interfaccia ActionListener (ascolta la tabella) e gestisce tutte le interazioni dell'utente
Quando l'utente esegue un'azione sulla tabella, questa classe controlla la riga attualmente selezionata e assegna alcuni valori all'azione dell'utente (in pratica, prende l'indice della riga selezionata quindi chiama tableModel.getValueAt (indexOfSelectedRow, someValuableDataColumnIndex))
Considerare ora lo scenario quando il sistema è sottoposto a stress test e le richieste vengono inviate costantemente con grande frequenza. Questo, nel mio caso, porta a un bug, quando a volte la classe che gestisce le azioni dell'utente riceve informazioni errate dal modello di tabella (l'azione è stata chiamata su una riga, ma l'azione viene eseguita per un'altra, di solito la prossima). Credo che ciò accada perché durante alcune fasi della gestione delle azioni il modello di tabella delle classi viene modificato a causa della nuova richiesta accettata.
La domanda è, come risolvere questo problema. Sto pensando di due approcci:
uso qualcosa di simile invokeAndWait() per l'inizializzazione in classe movimentazione mie azioni degli utenti (non piace questa idea, perché imo porterà ad altri bug imprevedibili)
creazione di una classe listener separata che ascolterà le selezioni dell'utente nella tabella e memorizzerà i dati dalla riga selezionata non appena è stata selezionata separatamente da TableModel. In questo modo le azioni di gestione delle classi prenderanno i dati non dal modello di tabella che viene modificato, ma dalla riga selezionata, che è costante durante lo scenario descritto. (non sono sicuro che questa idea funzioni)
Per favore, commenta le mie idee e suggerisci le tue.
Mi dispiace per l'assenza di qualsiasi codice qui, ma il codice originale occuperà troppo spazio e l'esempio di modello non è qualcosa che può essere fatto facilmente qui.
Dopo averci pensato un po 'per la mia seconda idea mi sono reso conto che non funziona. Ha gli stessi due passaggi: 1) ottenere l'indice di riga selezionato 2) ottenere informazioni dal modello di tabella per una riga con tale indice. Ogni nuova riga che appare in una tabella tra questi due passaggi rovinerà tutto. – GrayR
Quanti thread accedono a 'TableModel'? Se più di uno, come sincronizzano l'accesso? Vedi anche questo [sscce] (http://stackoverflow.com/a/7519403/230513) e questo [Q & A] (http://stackoverflow.com/q/7787998/230513). – trashgod
@trashgod TableModel è accessibile da un solo thread. Grazie anche per i collegamenti, informazioni interessanti. Non riesco a capire nulla di utile per ora, ma sicuramente lo esamineremo più profondamente. – GrayR