2013-08-09 12 views
6

Idealmente, la risposta sarà indipendente dalla piattaforma, ma sono utili anche le piattaforme specifiche, in particolare Oracle JVM. Il progetto a cui sto lavorando è ancora in esecuzione una JVM versione 6.Come segnalare la lunghezza della coda degli eventi AWT/Swing a livello di programmazione?

La particolare necessità ha a che fare con una GUI che si "congela" di volta in volta. Sono ben consapevole di fare sul lavoro con la GUI sull'EDT. Il programma stava funzionando bene su Windows, ma dopo essersi trasferito su Linux, questi "strani" problemi della GUI iniziarono ad accadere. In realtà, questo problema si è verificato in due applicazioni, sia dopo un passaggio da Windows a Linux. JVisualVM mostra oltre 10 milioni di oggetti java.awt.EventQueueItem. Il sospetto è che la coda AWT stia crescendo più velocemente di quella che viene servita su Linux, quindi l'idea è di inserire un indicatore della lunghezza della coda AWT nell'app e vedere cosa mostra quando la coda cresce/si riduce.

Un po 'di Google ha trovato this, ma esegue una scansione lineare della coda. Forse c'è un modo migliore?

+1

Per esplorare, è possibile intercettare gli eventi, come illustrato [qui] (http://stackoverflow.com/q/3158254/230513). – trashgod

+0

Dieci _million_! 'SetCoalesce (false)'? – trashgod

+0

No. Ci avevo già pensato e scansionato per questo. Non disattivare la logica di coalescenza. –

risposta

3

Oggetto interessante. Ho studiato il codice EventQueue un po ', e mentre io non ho risolto il problema, io possa avere alcune indicazioni utili:

  1. implementazione di Oracle di EventQueue non mantiene di dimensioni variabili, quindi a meno che prendere in consegna controllo completo di EventQueue (vedere 3), non c'è modo di fare meglio di una scansione lineare della coda quando si utilizza JRE di Oracle.
  2. È possibile scrivere il proprio EventQueue (probabilmente l'implementazione di Oracle di copia-incolla oltre a qualche ritocco ** sarà la più semplice) e utilizzare EventQueue.push(EventQueue) per installare la propria implementazione. Tutti gli eventi in coda saranno trasferiti alla tua coda, quindi puoi contarli mentre vengono registrati nella tua coda. Sfortunatamente, questa è ancora una scansione lineare, ma almeno ora è indipendente dalla piattaforma.
  3. In alternativa, è possibile installare la propria implementazione EventQueue (vedere 2) il prima possibile dopo aver creato la coda eventi originale (eseguire questa operazione in un blocco di codice statico all'inizio della classe che contiene il metodo principale). Quindi, l'implementazione può contare tutti gli eventi man mano che vengono pubblicati e non è necessario eseguire la scansione della coda quando si desidera conoscere la dimensione. Devi solo sperare che nessun altro spinga il proprio EventQueue in cima al tuo;)

** Alcuni tweaking: non ho provato questo, ma vorrei togliere tutto il codice statico pubblico/protetto (tutti che fa riferimento a quei metodi/variabili usa comunque java.awt.EventQueue, e così puoi), aggiungi la variabile dimensione e aggiorna questa variabile nei seguenti quattro metodi: postEvent(AWTEvent, int), getNextEventPrivate(), getNextEvent(int) e removeSourceEvent(Object, boolean).

un grosso problema con questa modifica è il fatto che l'EventQueue rende alcune chiamate ai metodi AWT con visibilità di default (ad esempio, Toolkit.getEventQueue() e Component.getAccessControlContext()), che non ti è permesso di chiamare in quanto l'implementazione sarà in un pacchetto differente . Dovrai trovare una soluzione alternativa per ogni caso individualmente.

+0

"copia-incolla" che cos'è ??, può estendere 'EventQueu' e quindi' spingere' la sua implementazione .. – nachokk

+0

Il problema è che è necessario modificare i metodi privati, il che significa riorganizzarli. Poiché tutto il codice di java.awt.EventQueue chiama i propri metodi privati, è necessario anche implementare nuovamente tali metodi. Questa catena di reimplementazione si arresta solo quando si raggiungono metodi pubblici o protetti. Inoltre, se la catena contiene metodi con visibilità predefinita che vengono richiamati da altrove in java.awt, diventa impossibile reindirizzare tutte le invocazioni ai metodi privati ​​alle proprie implementazioni. Per tutti gli scopi pratici, penso che sia meglio copiare e incollare. –

Problemi correlati