View Full Version : JAVA: eccezioni ingestibili
Ho costruito un JFrame con Java che contiene al suo interno, tra le altre cose, un JTree.
Siccome devo aggiornare periodicamente la visualizzazione di questo frame ho costruito un apposito Thread con questo codice
class Refresher extends Thread{
TopicNameSpaceFrame ilFrameDaAggiornare;
public Refresher(TopicNameSpaceFrame a){ilFrameDaAggiornare=a;}
public void run(){
this.setPriority(Thread.MIN_PRIORITY);
try{
while(true){
Thread.sleep(1000 * 10);
/*codice vario*/
ilFrameDaAggiornare.jTree.updateUI();
}
}catch(Exception e){/* qui non entra */}
}
Il codice fa quello che deve fare, solo che, puntualmente ogni 10 secondi (solo se il frame è visibile e solo se la riga in grassetto è presente nel codice) mi lancia una NullPointerException ke nn riesco a gestire e guardando lo stackTrace(ke ora nn posso postare :( ) vedo ke l'eccezione occorre solo in classi presenti in java.awt e in javax.swing e in nessuna classe del mio package.
Come faccio a gestirla o a evitarla?
non capisco, anche se NullPointerException discende da RuntimeException il catch dovrebbe intercettarla.
Sei sicuro arrivi dal codice dentro il try?
Si si.
Come dicevo le eccezioni nn occorrono nel mio codice ma solo nelle classi di java.awt e di javax.swing
Se riesco posto lo stack trace dell'eccezione.
Eccolo
java.lang.NullPointerException
at javax.swing.plaf.basic.BasicTreeUI.paint(Unknown Source)
at javax.swing.plaf.metal.MetalTreeUI.paint(Unknown Source)
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintWithOffscreenBuffer(Unknown Source)
at javax.swing.JComponent.paintDoubleBuffered(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
io nn so proprio ke fare...
non riesci a farne il catch allora perchè e' in un thread diverso.
perche' chiami updateUI? e' proprio necessario?
generalmente il chiamarlo espressamente incica qualche problema col model sottostante.
Se nn kiamo updateUI nn visualizzo i cambiamenti del JTree.
Le varie repaint update di Graphic nn danno nessun effetto
Cmq il Thread diverso dove nasce l'eccezione, da qello ke ho capito, lo fa Java con le sue API
Prova così:
while(true){
Thread.sleep(1000 * 10);
/*codice vario*/
try{
ilFrameDaAggiornare.jTree.updateUI();
}catch(Exception e){/* qui non entra */}
}
Ok proverò, domani t saprò dire (prima nn posso), cmq anke la sleep va in 1 blocco try-catch.
Xkè dovrebbe cambiare qalcosa?
Bhè innanzitutto è più corretto... quel while (true) indica che vuoi ripetere all'"infinito" il codice, il fallimento di una sleep o di un'updateUI non deve pregiuducare le successive esecuzioni... E poi... bhè, quando incontro un problema assurdo, rispondo con una soluzione ancora più assurda, magari mi va bene ;)
La soluzione nn era abbastanza assurda! Il problema è rimasto. Vabbè visto ke cmq l'esecuzione nn mi da problemi penso ke risolverò il problema così:
java mioPackage.mioMain 2> /dev/null
Okkio nn vede, cuore nn duole :D
Non credo sia la soluzione al problema perchè quanto scrivo evita problemi di dead-lock dovuti all'istruzione di aggiornamento grafico "arrembante". Ma non si sa mai.
while(true){
Thread.sleep(1000 * 10);
/*codice vario*/
ilFrameDaAggiornare.jTree.updateUI();
}
Questo pezzo è ad alto rischio. Tutte le istruzioni di aggiornamento grafico di un componente Swing devono essere delegate all'unico thread EventDispatcher.
La delega è realizzata in tutti i gestori di evento AWT: nell'esecuzione comune di un interfaccia grafica pertanto non c'è nulla da aggiungere (premo un bottone, il controllo passa ad un actionListener, nell'actionListener aggiorno un componente e tutto fila liscio, perchè ActionListener è "swing-safe". Vale per tutti i listener AWT).
Quando Thread diversi da EventDispatcher contribuiscono all'aggiornamento di un componente Swing entrano in gioco i metodi SwingUtilities.invokeLater(Runnable) e SwingUtilities.invokeAndWait(Runnable).
Quello che i metodi citati fanno è accodare le istruzioni contenute nel metodo "run()" del Runnable in argomento all'EventDispatcher.
Il primo accoda l'evento e restituisce immediatamente il controllo al chiamante, il secondo attende che l'esecuzione del "run()" sia completata (ecco perchè questo non può essere chiamato all'interno dell'EventDispatcher: attenderebbe sè stesso).
Forma corretta:
while(true){
Thread.sleep(1000 * 10);
/*codice vario*/
Runnable updater = new Runnable() {
public void run() {
ilFrameDaAggiornare.jTree.updateUI();
}
}
SwingUtilities.invokeLater(updater);
}
ilFrameDaAggiornare deve diventare "final". Normalmente è fattibile senza modifiche al codice salvo l'aggiunta di un "final" alla dichiarazione.
Ciao.
[update]
ho corretto qualche strafalcione di grammatica
Grazie mille.
Nn so se funzionerà, ma almeno adesso ne so d + su qello ke sto facendo.
Domani t saprò dire. Ciao
PGI, come al solito, ha ragione... Dai un'occhiata anche alla classe SwingWorker.
Per levarti la soddisfazione di capire il tipo di errore, catcha, invece che Exception, Throwable che è il papà di tutti gli errori. Anche la classe Throwable ha il metodo printSTackTrace()...
La soluzione d PGI funziona.
Invece catchando Throwable nn cambia niente, infatti l'errore era 1 NullPointerException e veniva generata in 1 altro Thread e qindi nn riuscivo a gestirla lì.
Grazie mille a tutti
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.