View Full Version : [JAVA] Aiuto sui thread e grafica
alessia86
10-09-2009, 14:35
Salve a tutti..non riesco a capire un problema..Sto facendo un videogioco..Ho usato frame e pannelli..ma qnd visualizzola grafica mi accade che tra un frame ed un altro ci sono delle interruzioni di circa 2 secondi..e dopo riappare la schermata...Non so se mi sono spiegata bene..Io ho pensato che siccome ho inserito alcuni thread..possano fare interferenza con il thread dell'awt...è possibile che se il problema è qst causano qst effetti??
Vi ringrazio !!! :confused:
nuovoUtente86
10-09-2009, 14:50
ricorda che le modifiche su elementi "visible" devono essere iniettati nel contesto dell' EDT
Il sintomo è quello di un sovraccarico dell'EDT (il thread che si occupa di aggiornare l'aspetto dei componenti e quello che gli va dietro).
Se usi un IDE con un profiler, il profiler è in grado di dirti cosa sta succedendo durante quelle interruzioni.
Altrimenti controlla i metodi repaint e tutti quelli che sono invocati come conseguenza di un aggiornamento dell'aspetto di un componente.
Verifica che non ci siano delle istruzioni che causano il caricamento di risorse da disco fisso, delle interruzioni tipo sleep o wait e controlla che un metodo direttamente o indirettamente invocato da repaint non causi esso stesso un'invocazione di repaint.
Salve a tutti..non riesco a capire un problema..Sto facendo un videogioco..Ho usato frame e pannelli..ma qnd visualizzola grafica mi accade che tra un frame ed un altro ci sono delle interruzioni di circa 2 secondi..e dopo riappare la schermata...Non so se mi sono spiegata bene..Io ho pensato che siccome ho inserito alcuni thread..possano fare interferenza con il thread dell'awt...è possibile che se il problema è qst causano qst effetti??
Vi ringrazio !!! :confused: io ho avuto esperienze di pesanti rallentamenti di interfacce Swing quando (erroneamente) creavo i vari componenti in un thread diverso dall'EDT anziché usare SwingUtilities.invokeLater.
PS: per cortesia, evita l'SMSese :Puke:
banryu79
11-09-2009, 13:06
Controllerei i metodi indicati da PGI e anche tutti i metodi delle eventuali implentazioni di listener vari, che sono eseguiti dall'EDT (actionPerformed() di ActionListener, per esempio: se nel corpo di questo metodo hai inserito del codice per calcolare i primi 1000 numeri primi l'EDT resta impegnato per un po').
alessia86
15-09-2009, 09:23
In effetti mi da quegli errori perchè ho creato dei thread che fanno interferenza con l'edt..ho provato a renderli thread 'demoni' ..e addesso tutti quelle interferenze non si vedono più..Ma va bene usare thread demoni opuure è meglio usare SwingUtilities.invokeLater? (anche se la SwingUtilities non ho capito bene come funziona)...
:confused:
banryu79
15-09-2009, 12:07
In effetti mi da quegli errori perchè ho creato dei thread che fanno interferenza con l'edt..ho provato a renderli thread 'demoni' ..e addesso tutti quelle interferenze non si vedono più..Ma va bene usare thread demoni opuure è meglio usare SwingUtilities.invokeLater? (anche se la SwingUtilities non ho capito bene come funziona)...
:confused:
Io non ho capito cosa fanno i thread che hai creato tu: mutano lo stato dei componenti grafici?
Se sì, allora tutte quelle operazioni che toccano direttamente componenti grafici visualizzabili vanno accodate nella AWT Event Queue in modo che sia l'EDT a processarle (come da architettura a thread singolo di AWT/Swing).
Per accodare delle operazioni nella event queue basta "impacchettarle" in un Runnable che passerai come argomento al metodo statico invokeLater() di SwingUtilities.
Come ti dicevo sopra, anche il codice che tu inserisci nel corpo dei metodi dei vari Listener (actionPerformed() per ActionListener e mousePressed(), mouseReleased(), mouseClicked(), di Mouselistener e mouseMoved(), mouseDragged() di MouseMotionListener(), tanto per citare i soiliti) viene processato dall'EDT, quindi, in questi casi, dovresti assicurarti di non far compiere computazioni che si protraggono "troppo" nel tempo, perchè finchè EDT è impegnato a processarle non può fare altro (ad esempio aggiornare la grafica dei componenti).
alessia86
15-09-2009, 12:15
Alcuni thread si..mentre altri no..Qst altri allora li devo fare demoni..in modo tale che la JVM termini ugualmente?
banryu79
15-09-2009, 12:26
Alcuni thread si..mentre altri no..Qst altri allora li devo fare demoni..in modo tale che la JVM termini ugualmente?
Dunque.. dove dici "alcuni thread sì": sono quelli che toccano la grafica?
Allora questi vanno accodati con invokeLater().
Dove dici: "mentre altri no"... dunque questi thread invece eseguono altre computazioni.
Questi non vanno accodati nell'EDT ma, se la grafica va poi aggiornata con una logica che dipende dal risultato di queste computazioni, bisogna in qualche modo sincronizzare le cose.
Sul fatto di renderli demoni o meno non saprei aiutarti, dato che fin'ora non mi è mai capitato di utilizzare thread impostati come "deamon" e non so usarli.
Ma mi pare di capire che tu li hai resi deamon più come un tentativo stile "ultima spiaggia" che a ragion veduta. Percui bisognerebbe sapere di più circa le operazioni logiche che devi eseguire e da cui eventualmente l'aggiornamento della grafica dipende.
Già sapere quali thread toccano la grafica e quali no è stato un primo passo. Potresti provare a descriverci cosa fanno i singoli thread? Questo sarebbe utile per capire più in dettaglio lo scenario in cui ti trovi.
alessia86
18-09-2009, 09:10
Alcuni thread invocano un metodo che si trova all'interno del pannello della grafica e qst metodo inoca un repaint..Qiundi qst thread vanno accodati con invokeLater(),giusto?
Poi ho un thread il cui compito è di rendere visibile un determinato pannello per un tot di tempo..ed invocano semplicemente setVisible(false) e setVisible(true)..
banryu79
18-09-2009, 09:27
Poi ho un thread il cui compito è di rendere visibile un determinato pannello per un tot di tempo..ed invocano semplicemente setVisible(false) e setVisible(true)..
Questo thread deve accodare sulla Event Queue solo l'invocazione del metodo setVisible() del tuo pannello.
Alcuni thread invocano un metodo che si trova all'interno del pannello della grafica e qst metodo inoca un repaint..Qiundi qst thread vanno accodati con invokeLater(),giusto?
No, in realtà non occorre, perchè esistono alcuni metodi che si possono invocare da qualsiasi thread.
Il metodo repaint() di JComponet (quind ereditato da JPanel) è uno di questi.
Se vuoi approfondire questi aspetti, o solo avere dei rapidi riferimenti sottomano per casi futuri, eccoti un buon link (http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html).
alessia86
18-09-2009, 15:45
Scusa se ti disturbo ancora..Ho accodato solo setVisible() nell'EventQueue..ma succede che mi visualizza lo sfondo di colore scuro del pannello ma non appare l'immagine che ho disegnato con paintComponent nel pannello..
Ora vorrei capire perchè cosi' non funziona mentre se uso un thread diverso il pannello viene visualizzato correttamente..
banryu79
18-09-2009, 16:07
Scusa se ti disturbo ancora..Ho accodato solo setVisible() nell'EventQueue..ma succede che mi visualizza lo sfondo di colore scuro del pannello ma non appare l'immagine che ho disegnato con paintComponent nel pannello..
Ora vorrei capire perchè cosi' non funziona mentre se uso un thread diverso il pannello viene visualizzato correttamente..
Nella event queue, assieme al setVisible(true) accoda un repaint().
Se continui a non ottenere ciò che desideri prova a postaci il codice del thread e del pannello, che gli diamo un'occhiata.
alessia86
19-09-2009, 08:08
Ho accodato anche il repaint() e ci siamo..addesso ho l'effetto che desidero..Vorrei solo capire un ultima cosa..in pratica dopo qst pannello che appare per un tot di tempo..devo far visualizzare un altro pannello..
Ma dopo aver fatto :
new Thread(new VisPannello()).start(); //VisPannello è il thread runnable dove accodo il setVisible() del pannello che voglio visualizzare per un tot di tempo
se dopo di qst chiamata metto:
PannelloG pg=new PannelloG();
F.add(pg);
pg.setVisible(true);
PannelloG è l'altro pannello che voglio far visualizzare dopo il precedente..
In qst modo però ottengo che appare direttamente pannelloG senza che il primo pannello..
Come posso fare per ovviare il problema?
Grazie !!!
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.