Besserer Programmierstil mit invokeLater?

javaprogger1987

Erfahrenes Mitglied
Hallo!
Ich habe in der letzten Zeit ein paar Blogs durchstöbert und bin des öfteren auf
Java:
SwingUtilities.invokeLater
gestoßen.
Ich dache mir - ist ja eigentlich ganz praktisch und auch besserer Stil - benutz das mal ;)
Also vorher sieht der Code so aus:
Java:
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        JXupper upper = new JXupper( this, log );
        [....]
        upper.uploadFile( file, password, thumb, thumbSize );
        
        while( !upper.finished() )
        {
            jProgressBar1.setValue( percent );
            this.update( this.getGraphics() );
            sleep( 100 );
        }
        
        String download = upper.getDownloadInformation()[0];
        String delete = upper.getDownloadInformation()[1];
        
        jTextField3.setText( download );
        jTextField4.setText( delete );
    }

Warum der Stil nicht so toll ist:
- Schleife in der actionPerformed Methode
- this.update( this.getGraphics );

Es ist nicht so das das nicht funktioniert - aber es gefällt mir nicht :)
Alternativ hatte ich mir gedacht:
Java:
[....]upper.uploadFile( file, password, thumb, thumbSize );
        SwingUtilities.invokeLater( new Runnable() {
        
            public void run()
            {
                while( !upper.finished() ) 
                {
                    jProgressBar1.setValue( percent );
                    try {
                        Thread.sleep( 100 );
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }            
        });[...]
wobei upper hier eine Klassenvariable ist...
Klappt aber so auch nicht - ProgressBar wird nicht aktualisiert..

Irgendwelche Tipps ;)
Gruß
Tobias
 
Hallo!

Mir scheint, dass du noch nicht ganz verstanden hast wozu (EventQueue/SwingUtitlities).invokeLater/invokeAndWait(...) eigentlich gut sind...
Swing ist nicht Thread-Safe. D.h. bestimmte Manipulationen (an der GUI / Komponenten) dürfen nur durch den Event Dispatch Thread (EDT) durchgeführt werden. Wird versucht eine nicht Threadsichere Komponente von Swing über einen anderen Thread als den EDT Thread zu manipulieren, dann kann es passieren, dass man eine Exception bekommt oder die GUI "einfriert". Genau um das zu vermeiden verwendet man nun an diesen Stellen je nachdem invokeLater bzw. invokeAndWait.

Siehe auch hier:
http://www.galileocomputing.de/open...sel15_032.htm#Rxx747java15032040005581F03B100

Für ein Beispiel zur JProgressBar schau mal hier:
Java:
/**
 * 
 */
package de.tutorials;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;
import javax.swing.JProgressBar;

/**
 * @author Tom
 * 
 */
public class ProgressBarExample extends JFrame {

    public ProgressBarExample() {
        super("ProgressBarExample");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        final JProgressBar progressBar = new JProgressBar(1, 100);
        progressBar.setStringPainted(true);
        add(progressBar);

        Executors.newSingleThreadExecutor().execute(new Runnable() {
            public void run() {
                int i = 0;
                while (true) {
                    i++;
                    i %= 100;
                    try {
                        TimeUnit.MILLISECONDS.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    progressBar.setValue(i);
                }
            }
        });

        pack();
        setVisible(true);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new ProgressBarExample();
    }

}


Gruß Tom
 
Okay danke schonmal :)
Hab mir das alles mal durchgelesen, habs aber so wirklich noch nicht verstanden :-(
-> http://www.galileocomputing.de/open...sel15_032.htm#Rxx747java15032040005581F03B100

An diesem Punkt steht, dass man alle Veränderungen an Swing-Elementen über den AWT(EDT?)-Thread machen soll.. Ist ein Setzten des Wertes der ProgressBar denn nicht genau das? Bzw. in welchen Fällen verwendet man die Methode dann?
NetBeans z.B. generiert mir standardmäßig folgende main-Methode für JFrame's:
Java:
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new JXupperGui().setVisible(true);
            }
        });
    }
Danke schonmal für die schnelle (und späte :)) Antwort!
Gruß
Tobias

//edit: Hab noch folgendes Beispiel gefunden, welches mich jetzt aber etwas verwirrt :D
http://www.galileocomputing.de/open...sel15_015.htm#Rxx747java15015040005471F039100
 
Zuletzt bearbeitet:
Zurück