SwingWorker Statusabfrage

Status
Nicht offen für weitere Antworten.

Liathne

Mitglied
Hallöchen zusammen,

ich bin gerade dabei eine kleine GUI zu entwickeln. Hierbei nutze ich SwingWorker um ein Array in einer for-Schleife abzuarbeiten. Das Array ist ein File-Array. Während der for-Schleife wird jedes im Array enthaltene Bild skaliert. Nun möchte ich nach jedem einzelnen Bild gerne die Dauer des Vorgangs und der Name des skalierten Bildes in einem JTextArea ausgeben. Ich bin jedoch bis jetzt kläglich daran gescheitert.


Dieser Aufruf erfolgt in der GUI Klasse:
Code:
//Erzeugung eines neuen SwingWorker Objektes
 final ScaleImages si = new ScaleImages(imagefile, SCALING,
                        Integer.parseInt(scale_width.getText()), Integer.parseInt(scale_length.getText()), outputDir );
                si.execute();
                
//Versuch eine Property abzufragen
                si.addPropertyChangeListener(
                        new PropertyChangeListener() {
                    public  void propertyChange(PropertyChangeEvent evt) {                       
                        if ("schleifenlauf".equals(evt.getPropertyName())) {
                            log.append("Scaled: " +si.getImagefile()[si.getSchleifenlauf()].getName()+" in "+si.getDauer()+" ms."+"\n");
                            showImageLabel.setIcon(new ImageIcon(si.getScaledImage()));                            
                        }
                       
                    }
                    
                });

Der Schleifenaufruf in der SwingWorker Klasse
Code:
  protected int doInBackground() throws Exception {
        for (int i=0;i<getImagefile().length;++i){
            long startzeit = System.currentTimeMillis();
                        
            setImage(javax.imageio.ImageIO.read(getImagefile()[i]));
            
            setScaledImage(scaleImage(getImage(), getScaling(), getWidth(), getLength()));
                        
            String filename = getImagefile()[i].getName();
            filename = filename.substring(0, filename.indexOf(".jpg"));
            String outputdir = getOutputDir().toString()+File.separatorChar+filename+".bmp";
            
            BufferedImage buffimage = createBufferedImage(getScaledImage());
            
            ImageIO.write(buffimage, "bmp", new File( outputdir ) );
            long endzeit = System.currentTimeMillis();
            
            setDauer(endzeit-startzeit);
            
          //this.setProgress(i) funktioniert, allerding kann hierbei i max. 100 sein, was zu klein ist

            this.setSchleifenlauf(i);
            
            return schleifenlauf;            
        }
        
    }

Nochmal zusammenfassend:
Ich benötige den Wert des aktuellen i in der GUI-Klasse, wie ist das zu realisieren?

Danke für Eure Hilfe.
 

Marco13

Top Contributor
Das Beispiel oben in der SwingWorker-Doku könnte helfen:
http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html

Wenn du (wie dort beschrieben) einen SwingWorker<???, Integer> erstellst, und dann in der doInBackground die Methode "publish(i)" aufrufst, bekommst du dir in deiner implementierung von "process(List<Integer> chunks)" die liste der i's, die bisher durchgeacktert wurden.... Und process wird im EDT aufgerufen, d.h. von dort aus kannst du die Information über das aktuelle i (d.h. das letzte element der Liste) ans GUI weiterreichen.
 

Liathne

Mitglied
Ich hab nun folgendes erstellt

Code:
    protected List<Integer> doInBackground() throws Exception {
        for (int i=0;i<getImagefile().length;++i){
            long startzeit = System.currentTimeMillis();
            
            setImage(javax.imageio.ImageIO.read(getImagefile()[i]));
            
            setScaledImage(scaleImage(getImage(), getScaling(), getWidth(), getLength()));
            
            String filename = getImagefile()[i].getName();
            filename = filename.substring(0, filename.indexOf(".jpg"));
            String outputdir = getOutputDir().toString()+File.separatorChar+filename+".bmp";
            
            BufferedImage buffimage = createBufferedImage(getScaledImage());
            
            ImageIO.write(buffimage, "bmp", new File( outputdir ) );
            long endzeit = System.currentTimeMillis();
            
            setDauer(endzeit-startzeit);           
            
            publish(i);
            
        }
        return schleifenlauf;
    }
    
    @Override
    protected void process(List<Integer> chunks) {
        for (int i : chunks) {
             schleifenlauf.add(i);
         }
    }

Aber wie kann ich nun in meiner GUI-Klasse auf schleifenlauf zugreifen?
 

*Hendrik

Bekanntes Mitglied
Ich beziehe mich mal auf das Beispiel von Sun
Code:
    private static class FlipPair {
        private final long heads, total;
        FlipPair(long heads, long total) {
            this.heads = heads;
            this.total = total;
        }
    }

    private class FlipTask extends SwingWorker<Void, FlipPair> {
        @Override
        protected Void doInBackground() {
            long heads = 0;
            long total = 0;
            Random random = new Random();
            while (!isCancelled()) {
                total++;
                if (random.nextBoolean()) {
                    heads++;
                }
                publish(new FlipPair(heads, total));
            }
            return null;
        }

        @Override
        protected void process(List<FlipPair> pairs) {
            FlipPair pair = pairs.get(pairs.size() - 1);
            headsText.setText(String.format("%d", pair.heads));
            totalText.setText(String.format("%d", pair.total));
            devText.setText(String.format("%.10g", 
                    ((double) pair.heads)/((double) pair.total) - 0.5));
        }
    }

Die SwingWorker-Klasse ist eine innere Klasse des GUI - wie ist es bei Dir? Entsprechend zu dem Beispiel könntest Du die Zeit für die Skalierung und den Bildnamen in einem separaten Objekt speichern (vielleicht hast Du dafür ja bereits etwas vorgesehen) und dieses durch publish an die Methode process() übergeben. Dort mußt Du dann nur noch Dein GUI mit den entsprechenden Werten aus Deinem übergebenen Objekt aktualiesieren.
 

Marco13

Top Contributor
Code:
    protected List<Integer> doInBackground() throws Exception 
    {
           
        ....publish(i);
            
        return schleifenlauf;
    }
    
    protected void process(List<Integer> chunks) {
        for (int i : chunks) {
             schleifenlauf.add(i);
         }
    }

Nee, "schleifenlauf" wäre in diesem Fall das Endergebnis. In der "process"-Methode sollte nichts zum Endergebnis hinzugefügt werden. 'process' ist wirklich NUR für Zwischenergebnisse. Wenn die doInBackground-Methode nichts zurückgeben muss, kannst du einen SwingWorker<Void, Integer> erstellen, und dann
Code:
Void doInBackground() ... // Void groß geschrieben!
{
    ... publish(i);

    return null;
}
machen.

Aber wie kann ich nun in meiner GUI-Klasse auf schleifenlauf zugreifen?

Musst du vielleicht garnicht. Eher umgekehrt. Irgendwo könnte dann z.B. bei dir sowas stehen:

Code:
public void startTheTask()
{
    final GUI gui = holDieGUICompnenteWoWasAngezeigtWerdenSoll();

    SwingWorker<Void, Integer> task = new SwingWorker<Void, Integer>
    {
        protected Void doInBackground() throws Exception 
        {
             for (i...)
             {
                  ...
                  publish(i);
             }
        }

        protected void process(List<Integer> chunks) 
        {
            int i = chunks.get(chunks.size()-1);
            gui.schreibeInformation(i); // Schreibt eine Information ins GUI, dass man gerade bei Schritt 'i' ist
        }
    }
    task.execute();
    task.get();
}
 

Marco13

Top Contributor
Hab nochmal in den Eröffnungsbeitrag gesehen. Du könntest das z.B. so machen
Code:
class ScaleImages extends SwingWorker<Void, Integer>
{
    private JTextArea textArea;
   
    public ScaleImages(JTextArea textArea, ... )
    {
        this.textArea = textArea;
        ...
    }

    ...doInBackground...

    protected void process(List<Integer> chunks)
    {
        int i = chunks.get(chunks.size()-1);
        textArea.setText(""+i); // Schreibt eine Information ins GUI, dass man gerade bei Schritt 'i' ist
    } 
}

D.h. du kannst deiner SwingWorker-Klasse die Component übergeben, wo die Information reingeschrieben werden soll.

Erstellt wird er dann eben mit

final ScaleImages si = new ScaleImages(ausgabeTextArea, imagefile, SCALING, Integer.parseInt(scale_width.getText() ...);

Die TextArea ist nur ein Beispie - je nachdem, wie und wo bei dir die Anzeige sein soll, kann es auch eine andere Component sein...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
ralfb1105 Swing Frage zu SwingWorker Verhalten bei cancel() AWT, Swing, JavaFX & SWT 2
ralfb1105 Swing SwingWorker - max 10 Threats werden gestartet !? AWT, Swing, JavaFX & SWT 5
ralfb1105 Swing Ausführung einer SwingWorker Klasse stoppen AWT, Swing, JavaFX & SWT 4
ralfb1105 Swing Timer in SwingWorker stoppen AWT, Swing, JavaFX & SWT 4
S Swing SwingWorker - richtige Implementierung doInBackground() AWT, Swing, JavaFX & SWT 5
H Swing BufferedReader.close() hängt im SwingWorker AWT, Swing, JavaFX & SWT 1
Nuiton Swing SwingWorker - Prozess stoppen AWT, Swing, JavaFX & SWT 4
Thallius Auf Swingworker warten? AWT, Swing, JavaFX & SWT 5
M SwingWorker Hilfe! AWT, Swing, JavaFX & SWT 10
J Swing Nach SwingWorker Funktion aus der GUI Klasse aufrufen AWT, Swing, JavaFX & SWT 5
C Swing SwingWorker abbrechen AWT, Swing, JavaFX & SWT 12
C Swing SwingWorker: Auf beendigung eines Formulars / einer Arbeit warten AWT, Swing, JavaFX & SWT 10
Psypsy Swing SwingWorker unterschied zwischen setProgress und process AWT, Swing, JavaFX & SWT 2
A Swingworker rückgabewert verwenden AWT, Swing, JavaFX & SWT 9
B Frage zu Swing,Threads, SwingWorker und Socket Communikation AWT, Swing, JavaFX & SWT 4
M Prioritäten bei SwingWorker / Threads AWT, Swing, JavaFX & SWT 9
M Liste mittels SwingWorker füllen klappt nicht AWT, Swing, JavaFX & SWT 10
Iron Monkey SwingWorker verschwindet nicht AWT, Swing, JavaFX & SWT 10
X Prozess mit Runtime.getRuntime in SwingWorker aufrufen AWT, Swing, JavaFX & SWT 6
R Zugriff auf Model im MVC-Design aus SwingWorker heraus AWT, Swing, JavaFX & SWT 3
G SwingWorker setProgress Problem AWT, Swing, JavaFX & SWT 17
K Frage zu ProgressBar, SwingWorker etc. AWT, Swing, JavaFX & SWT 4
G SwingWorker AWT, Swing, JavaFX & SWT 2
J Unterschied zwischen SwingWorker und Threads AWT, Swing, JavaFX & SWT 4
S SwingWorker :( AWT, Swing, JavaFX & SWT 6
F swingworker und eventdispatch thread AWT, Swing, JavaFX & SWT 9
S SwingWorker - ich werde wahnsinnig AWT, Swing, JavaFX & SWT 4
0 SwingWorker Tutorial ? AWT, Swing, JavaFX & SWT 2
L SwingWorker Thread pausieren AWT, Swing, JavaFX & SWT 12
M Kann ein SwingWorker nur einmal laufen? AWT, Swing, JavaFX & SWT 2
J SwingWorker, get und boolean AWT, Swing, JavaFX & SWT 6
V Statusabfrage von JCheckBox und JComboBox AWT, Swing, JavaFX & SWT 7

Ähnliche Java Themen

Neue Themen


Oben