PDA

View Full Version : [JAVA] Uso di SwingUtilities.invokeLater


futu|2e
01-07-2011, 21:38
Ciao, vi illustro la situazione:

Ho una finestra creata in Swing, contenente un pannello vuoto e una voce di
menu in alto dove alla sua pressione si apre il browsing del file system per
selezionare un file (JFileChooser).

Alla selezione del file ho bisogno di agire sul pannello vuoto, disegnando
un oggetto di tipo JTree.

Qui nasce il problema, nel momento in cui io aggiungo l'oggetto JTree al mio
pannello, qual'è la procedura corretta per "ri-disegnare" qualcosa sul mio
frame / finestra?

Girovangando su internet ho scoperto che è possibile, una volta aggiunto
l'oggetto al mio pannello, richiamare il setVisibile direttamente dal frame:

pannello.add(jtree);
frame.setVisible(true);

E in effetti funziona, ma ho letto di altri utenti che non erano d'accordo sull'
uso e consigliavano vivamente l'uso del InvokeLater senza bisogno del
setVisibile nuovamente.

Nel mio caso:

SwingUtilities.invokeLater
(
new Runnable()
{
public void run()
{
pannello.add(jtree);
}
}
);

Ora, se io inserisco questa porzione di codice al posto del semplice "add"
di prima, non fa proprio nulla.

Sapete aiutarmi come si deve agire ogni volta per ri-disegnare qualcosa
su un frame?

Vi ringrazio :)

banryu79
03-07-2011, 09:55
Confesso di non aver capito quale è il problema, forse uno spezzone di codice aiuterebbe.

Comunque: SwingUtilities.invokeLater (o EventQueue.invokeLater, è lo stesso) serve ad accodare del codice (il Runnable) nella event queue di swing/awt in modo che venga poi processato in modo asincrono dall'edt (event dispatcher thread) il thread che in Swing/Awt processa tutti gli eventi grafici.

Per "ridisegnare" il componente prova con un repaint e se non bastasse un revalidate

tuccio`
03-07-2011, 10:45
tutte le operazioni su componenti swing vanno fatte nell'edt, perché siano thread safe, e quindi non nel main.. non a caso tutti gli esempi sul sito di oracle sono fatti in questo modo http://download.oracle.com/javase/tutorial/uiswing/examples/start/HelloWorldSwingProject/src/start//HelloWorldSwing.java

futu|2e
04-07-2011, 13:13
Confesso di non aver capito quale è il problema, forse uno spezzone di codice aiuterebbe.

Mi sono spiegato forse con confusione, in pratica: dopo aver creato
e disegnato una finestra contenente pannelli, come fare per disegnarci sopra
in un secondo momento altri oggetti dentro ai pannelli.

Per "ridisegnare" il componente prova con un repaint e se non bastasse un revalidate

Che è lo stesso consiglio che ho avuto da altre persone, stasera lo proverò
e vi farò sapere.

Grazie

banryu79
04-07-2011, 13:54
Mi sono spiegato forse con confusione, in pratica: dopo aver creato
e disegnato una finestra contenente pannelli, come fare per disegnarci sopra
in un secondo momento altri oggetti dentro ai pannelli.

La confusione mi deriva dall'uso che fai della parola "disegnare" in questo contesto: intendi "visualizzare" (della serie: aggiungere/aggiornare nuovi componenti in una finestra visibile) oppure parli proprio di "custom rendering" (hai un component, tipicamente un JPanel o un Canvas, sul quale esegui un tuo rendering personalizzato)?

Nel primo caso si tratta di invocare un aggiornamento del rendering con repaint o revalidate, nel secondo caso è tutta un'altra faccenda.

P.S.: se posti il codice probabilmente si fa prima.