PDA

View Full Version : [JAVA]Problema coin i Thread e swing


tccgen
22-09-2008, 15:10
Ho creato un finestra principale.
Alle pressione del tasto.
Vengono creati due thread,uno che mostra una jdialog ed una che esegue un 'operazione.
Alla fine dell'operazione va a scrivere sullo stdout OK.
All'interno della jdialog deve comparire una scritta.
Il problema è quando visualizzo la jdialog la scritta non viene visualizzata ma viene visualizzato solo al termine dell'operazione perchè succede questo??



public class Ascoltatore implements ActionListener {
private FinestraPrincipale fp;

/**
* @param args the command line arguments
*/

public Ascoltatore(){
fp = new FinestraPrincipale(this);

}


public final void istancePanelProgres(){
PanelProgres pp = new PanelProgres(fp);
}
public final void istanceOperation(){
Operazione o = new Operazione();
}

public static void main(String[] args) {
// TODO code application logic here
new Ascoltatore();

}

public void actionPerformed(ActionEvent e) {

if(e.getActionCommand().equals("premi")){

Thread t = new Thread(new Runnable(){

public void run() {
istancePanelProgres();
}

});

Thread t1 = new Thread(new Runnable(){

public void run() {
istanceOperation();
}

});

t1.start();
t.start();
try {
t1.join();
System.out.println("Ok");
} catch (InterruptedException ex) {
Logger.getLogger(Ascoltatore.class.getName()).log(Level.SEVERE, null, ex);
}

}
}

public class FinestraPrincipale extends JFrame{
public FinestraPrincipale(Ascoltatore asc){
this.setTitle("Example");
this.setBounds(0, 0, 700, 700);
JButton jbutton = new JButton("premi");
jbutton.addActionListener(asc);
this.add(BorderLayout.NORTH,jbutton);
this.setVisible(true);
}
}



public class PanelProgres {
public PanelProgres(JFrame frame){
JDialog jdialog = new JDialog(frame,"jdialog",true);
JPanel jpanel = new JPanel();
jpanel.add(new JLabel("Waiting..Working in progres"));
jdialog.getContentPane().add(jpanel);
jdialog.setBounds(100, 100, 300, 100);
jdialog.setVisible(true);


}
}

public class Operazione {
public Operazione(){
for(int i = 0 ;i<10000;i++){
System.out.println("Ciao");
}
}

}

tccgen
23-09-2008, 10:21
Se non vorrei utilizzare join( ) come potrei fare per attendere la teminazione di un thread

tccgen
24-09-2008, 11:01
Allora nessuna idea?

andbin
24-09-2008, 14:09
Il problema è quando visualizzo la jdialog la scritta non viene visualizzata ma viene visualizzato solo al termine dell'operazione perchè succede questo??Il concetto importantissimo da capire è che Swing non è thread-safe. Esiste un thread, chiamato generalmente EDT, event dispatch thread, che è il thread che si occupa di "disegnare" la interfaccia utente e, tra le altre cose, dispacciare gli eventi ai listener.
Salvo casi particolari (e ben documentati), l'accesso alla interfaccia utente (impostazioni sui componenti, modifiche sui layout, ecc...) va fatto solo nel contesto del EDT.

Quando viene invocato un metodo di un listener (es actionPerformed) si è nel contesto del EDT. Tu hai fatto una join() su un thread. Questo vuol dire che stai tenendo tu impegnato il EDT e finché sei tu che lo blocchi, il controllo non può ritornare al framework e quindi aggiornare la interfaccia utente, che pertanto rimane "congelata".