GUI "geblockt" & Nachrichten an die GUI

Status
Nicht offen für weitere Antworten.

DiGiT79

Mitglied
Hallo,

eins vorweg: Ich bin neu im Java Umfeld! Also habt bitte Nachsicht :)

Ich versuche grad meine ersten Schritte und komme auch stetig weiter.

Eine kleine GUI habe ich erstellt und auch einige Funktionen in die Buttons programmiert (ich weiss,hab heute gelesen man sollte sowas eigentlich immer strikt trennen...also GUI von der Logik...kommt beim 2. Prog).

Alles funktioniert auch....fast alles.

Hinter einem Button liegt eine Schleife...In jedem Durchgang werden Files umbenannt/kopiert, und ein "Logeintrag" in eine jTextArea per append() angehangen.

Jedoch sehe ich die Ausgabe erst, wenn die komplette Schleife durchlaufen wurde.

Nach etwas rumstöbern und lesen denke ich wohl ich sollte die "Schleifenlogik" in einen eigenen Thread stecken, und diesen losgelöst von der GUI starten wenn der Button gedrückt wird.

Irgendwie muss ich dann halt noch eine "Nachricht" an die GUI schicken mit dem String des LogEintrags.

Sind Threads in diesem Moment die richtige Herangehensweise, oder bin ich damit auf dem Holzweg und ich könnte es "simpler" lösen ? Gibt es sowas wie "Nachrichten", die ich zwischen den einzelnen Programmteilen dann übergeben kann ?

Vielen Dank im Vorraus für eure Antworten.

Gruß

DiGiT79
 
Könntest du vielleicht ein wenig von deinem Code posten? Vielleicht bin ich ja grad ein bisschen verwirrt, aber eigentlich braucht man keine Threads dafür. Zeig doch mal, wie du das porgramiert hast (die relevanten Stellen).
 

The_S

Top Contributor
Schau dir mal

SwingUtilities#invokeLater

an. Dazu findest du auch einige Beispiele mit der Forensuche.
 

DiGiT79

Mitglied
Ist mir zwar peinlich, aber ok :) Wenns hilft...

jTextArea1.append(targetParent);

Die Zeile ist derzeit nur zum testen... da soll später dann der "echte" Logeintrag rein...

Allerdings ist die GUI für die Zeit der Schleife (dauert nen paar sec bei ca. 100 Bilder die durchlaufen werden) blocliert, und ich sehe erst hinterher alle "Logeinträge"...


Anmekrung: Ich will Bilder einer Digitalkamera auf der HDD sortieren.... anhand ihrer EXIF Daten.



Code:
    private void b_executeActionPerformed(java.awt.event.ActionEvent evt) {                                          
        int i;
        for (i = 0; i < sourceFiles.length ; i++) {
            jTextArea1.append(targetDir + File.separator + sourceFiles[i].getName());
            jTextArea1.append("\n");
            String srcDate = getExifDate(sourceFiles[i]);
                       
            String day, month, year = null;
            String[] tempdate = srcDate.split(":");
            year = tempdate[0]; month = tempdate[1]; day = tempdate[2];
                        
            
            String targetfile;
            targetfile = targetDir + File.separator  + year + "_" + month + "_" + day + File.separator + sourceFiles[i].getName();
           
            
            String targetParent = targetDir + File.separator  + year + "_" + month + "_" + day + File.separator;
            jTextArea1.append(targetParent);
            
            File target_Parent = new File(targetParent);
            
           boolean pDirExists = target_Parent.exists();
            if (!pDirExists) {
                target_Parent.mkdirs();
            }
            
            
            if (cb_sourceFiles.isSelected()) {
                boolean success = sourceFiles[i].renameTo(new File(targetDir + File.separator + sourceFiles[i].getName()));
            } else {
                try {
                    copyFile( sourceFiles[i].toString(), targetfile);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }


PS: Ich hoffe ich werde hier für so "Chaos Code" nicht gelyncht :)
 

DiGiT79

Mitglied
danke,der link ist klasse!

damit bekomme ich es hin,dass die gui "responsive" bleibt...

aber: so wie ich das sehe habe ich die Logzeilen hinterher dennoch "alle auf einen Schlag" , oder ?

Ich wuerd zu gern nach jedem Bild was verarbeitet wurde eine Logzeile sehen...aber fuer jedes Bild einen Eigenen Thread starten is doch Overkill,oder ?
 

Wildcard

Top Contributor
Der Thread kann ja nach und nach Rückmeldung geben.
Gleiches Prinzip wie bei einem ProgressBar.
 
G

Guest

Gast
ok,danke fuer den tipp!
ich schaue mir mal das prinzip "progress bars mit swingworker" an, vielleicht komme ich damit weiter!
 

DiGiT79

Mitglied
So,diesmal schreibe ich auch wieder mit meinem Nick :)

Der Tipp mit dem SwingWorker funktioniert prima!
Der Thread wird gestartet, und tut auch was er soll.

Gibt es aber eine einfache Möglichkeit aus der For Schleife im SwingWorker Thread heraus bei jedem Durchlauf eine Komponente der GUI upzudaten ?

Zb bei jedem durchlauf eine neue Zeile in eine jTextArea zu appenden (und sei es erstmal nur die Laufwvariable der for Schleife...) ?
Irgendwie sehe ich da den Wald vor lauter Bäumen nicht...

Vielleicht habt ihr ein Stichwort für mich parat...

Hier mal der Code Ausschnitte aus der SwingWorker Klasse:

Code:
@Override
    public String[] doInBackground() {
        String[] logData = new String[source.length] ;
        for (int i = 0; i < source.length ; i++) {
            
           .....
            
        }
        return logData;
    }


Und hier wird der Thread gestartet (in einem Eventhandler eines Buttons in der GUI):

Code:
 private void b_executeActionPerformed(java.awt.event.ActionEvent evt) {                                          
        
        ExifDateFinderSW worker = new ExifDateFinderSW();
        worker.setSourceFiles(sourceFiles);
        worker.setTargetDir(targetDir);
        worker.execute();
       
    }
 

DiGiT79

Mitglied
Update:

So funktioniert es nun:

Code:
    final ExifDateFinderSW worker = new ExifDateFinderSW();
        worker.setSourceFiles(sourceFiles);
        worker.setTargetDir(targetDir);
        worker.execute();
        //        b_execute.setText("" + worker.getProgress());
        
                
         
     worker.addPropertyChangeListener(
     new PropertyChangeListener() {
         public  void propertyChange(PropertyChangeEvent evt) {
             if ("progress".equals(evt.getPropertyName())) {
                 jTextArea1.append("" + worker.getProgress());
                 jTextArea1.append("\n");
             }
         }
});


Kann mir jemand beantworten warum ich das final setzen muss ?
Das hatte mir die IDE angemeckert...
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben