Swing JProgressBar läuft nicht mit

Snuke

Mitglied
Ich habe wiedermal ein Problem...


Und zwar habe ich eine JProgressBar die mir den Stand des Kopierens anzeigen soll. Extra Threads soll man ja nicht nutzen.

Java:
localPBar = new JProgressBar();
localPBar.setStringPainted(true);
localPBar.setMinimum(0);

und in einem ActionListener hab ich dann (auf Knopfdruck)

Java:
localPBar.setMaximum(vItemsToCutCopy.size());
					localPBar.setValue(0);
					localPBar.setVisible(true);
					
					
					synchronized (vItemsToCutCopy) 
					{
						for(int i = 0; i < vItemsToCutCopy.size(); i++)
						{
							Tree t = (Tree)vItemsToCutCopy.get(i);
							
							File fOld = new File(t.getPath());
							
							if(!fOld.exists())
							{
								localPBar.setMaximum(localPBar.getMaximum()-1);
								
								continue;
							}
							
							File fNew = new File(localPath.getText()+t.getName());
							
							if(localIsCut)
							{
								fOld.renameTo(fNew);
							}else{
								try
								{
									if(fOld.isDirectory())
									{
										copyLocalDirectory(fOld,fNew);
										
										continue;
									}
									
									FileChannel inChannel = new FileInputStream(fOld).getChannel();
									FileChannel outChannel = new FileOutputStream(fNew).getChannel(); 
									inChannel.transferTo(0, inChannel.size(), outChannel);
									
									localPBar.setValue(localPBar.getValue()+1);
									
									
								}
								catch(FileNotFoundException e1){}
								catch(IOException e2){}
							}
							
							
							
							t = null;
							fOld = null;
							fNew = null;
						}
					}
					
					vItemsToCutCopy.removeAllElements();
					
					localPBar.setVisible(false);
					localPBar.setValue(0);

hier ist auch noch die copyDir:

Java:
private void copyLocalDirectory(File fOld,File fNew)
	{
		File[] files = fOld.listFiles();
		
        fNew.mkdirs();
        for (File file : files) 
        {
            if (file.isDirectory()) 
            {
            	copyLocalDirectory(file, new File(fNew.getAbsolutePath() + System.getProperty("file.separator") + file.getName()));
            }else{
            	try
            	{
	            	FileChannel inChannel = new FileInputStream(file).getChannel();
					FileChannel outChannel = new FileOutputStream(fNew.getAbsolutePath() + System.getProperty("file.separator") + file.getName()).getChannel(); 
					inChannel.transferTo(0, inChannel.size(), outChannel);
					
					localPBar.setValue(localPBar.getValue()+1);
					
					
            	}
				catch(FileNotFoundException e1){}
				catch(IOException e2){}
            }
        } 
        
        files = null;
        fOld = null;
        fNew = null;
	}


Das Problem ist das die JProgressBar nicht aktuell ist... d.h. sie wird gar nicht angezeigt.

lg
 

Michael...

Top Contributor
Extra Threads soll man ja nicht nutzen.
Heißt genau? Grundsätzlich muss das kopieren der Daten in einem separaten Thread laufen - wie auch immer man das implementiert. Wenn man den Vorgang im EDT laufen lässt, kann sich die Progressbar nicht aktualisieren bzw. in Deinem Fall gar nicht erst angezeigt.
Die Änderung des Fortschritts der ProgressBar würde ich an einer zentralen Stelle machen.
 

Snuke

Mitglied
Wenn man den Vorgang im EDT laufen lässt, kann sich die Progressbar nicht aktualisieren bzw. in Deinem Fall gar nicht erst angezeigt.
Die Änderung des Fortschritts der ProgressBar würde ich an einer zentralen Stelle machen.


Ich hab mich etwas eingelesen in das ganze GUI zeug... Ich bin mir allerdings nicht sicher wie man das am bestem umsetzt.


Angenommen ich baue mir eine Funktion:

Java:
private void copy(String from, String to)
{
}

Kann ich bei jedem Funktionsaufruf einen neuen Thread starten?

Java:
private void copy(String from, String to)
{
    Thread t = new Thread(new Runable()
    {
        ...... (run methode und in dieser kopieren sowie die JProgressBar inkrementieren)
    }
}

Denn meine bedenken sind einfach, dass wenn ich 1000 Dateien kopiere das doch ziemlich lastig (immerhin sind das dann 1000 Threads) wird oder nicht?

Oder sollte man am besten mit dem SwingUtilities.invokeLater arbeiten?


lg
 

Natac

Bekanntes Mitglied
Wo du den neuen Thread startest ist deine Sache. Möchtest du die Dateien hintereinander oder parallel kopieren?

Wichtig ist, dass der Kopier-Thread pro Fortschritt eine Runnable-Instance der
Code:
StringUtil.invokeLater
gibt. Diese Runnable Instanz aktualisiert dann deinen ProgressBar.
 

Snuke

Mitglied
Wo du den neuen Thread startest ist deine Sache. Möchtest du die Dateien hintereinander oder parallel kopieren?

Wichtig ist, dass der Kopier-Thread pro Fortschritt eine Runnable-Instance der
Code:
StringUtil.invokeLater
gibt. Diese Runnable Instanz aktualisiert dann deinen ProgressBar.


Ich möchte die Dateien hintereinander kopieren... Dann komme ich also mit einem Thread der das kopieren und updaten der JProgessbar verwaltet aus?
 

Michael...

Top Contributor
Mit invokeLater kannst Du bewusst Code in den EDT (für Darstellung und aktualisierung der GUI verantwortlichen Thread) einschieben. Die "Gefahr" besteht darin, dass Du darin längere Berechnungen oder Deinen Kopiervorgang ausführen lässt.
Aber diese Gefahr besteht immer - auch bei Nutzung des SwingWorkers.

Der Unterschied (Vorteil) beim SwingWorker (ggüber dem direkten erzeugen von Threads) ist, dass Du Dich nicht selbst um das Erstellung eines neuen Threads kümmern musst. SwingWorker hat bestimmte Sachen bereits implementiert und bietet die Methode
Code:
doInBackground()
Alles was hier drinsteht wird in einem durch den Worker erzeugten Thread ausgeführt. Nach Abschluss dieser Methode wird "automatisch" die Methode
Code:
done()
aufgerufen. Diese läuft dann wiederum im EDT.
Um das alles kümmert sich der SwingWorker.

In Deinem Fall willst Du aber regelmäßig den Zwischenstand des Hintergrundprozesses an die GUI übermitteln. Das bedeutet, dass auch wenn Du den SwingWorker benutzt und den Kopierprozess in der
Code:
doInBackground()
durchführen lässt, Du innerhalb der doInBackground die Statusaktualisierung an die GUI per invokeLater() an die GUI "weitermelden" musst.

Es gibt also keine Vor/Nachteile zw. SwingWorker und invokeLater(), weil die auf unterschiedlicher "Ebene" stehen. SwingWorker nimmt dem Programmierer nur das erstellen eines neuen Threads ab und kümmert sich um ein paar Sachen. Aber in beiden Fällen kann die Verwendung von invokeLater() notwendig sein.

[EDIT]Wobei ich jetzt ganz vergessen habe, dass der SwingWorker (ich benutze ihn leider nie) eigene Mechanismen hat (
Code:
publish(...)
), um Informationen aus dem Hintergrund Thread in den EDT zu übertragen.[/EDIT]
 
Zuletzt bearbeitet:

Snuke

Mitglied
Vielen Dank für die ausführliche Erklärung :)... Ich werde das mal mit SwingWorker ausprobieren und dann direkt das Ergebniss Posten
 

Snuke

Mitglied
So ich habe das ganze ausprobiert aber komme nicht wirklich zurecht. Dateien kann ich Perfekt auf diese Art kopieren. Aber wenn es an einen Ordner samt Inhalt geht, funktioniert das nicht mehr.

Meine CopyDir sieht jetzt so aus:

Java:
private void copyLocalDirectory(File fOld,File fNew)
    {
        File[] files = fOld.listFiles();
        
        fNew.mkdirs();
        for (File file : files) 
        {
            if (file.isDirectory()) 
            {
                copyLocalDirectory(file, new File(fNew.getAbsolutePath() + System.getProperty("file.separator") + file.getName()));
            }else{
                try
                {
                    FileChannel inChannel = new FileInputStream(file).getChannel();
                    FileChannel outChannel = new FileOutputStream(fNew.getAbsolutePath() + System.getProperty("file.separator") + file.getName()).getChannel(); 
                    inChannel.transferTo(0, inChannel.size(), outChannel);
                    
                    localPBar.setValue(localPBar.getValue()+1);
                    System.out.println(localPBar.getMaximum());
                    
                }
                catch(FileNotFoundException e1){}
                catch(IOException e2){}
            }
        } 
        
        files = null;
        fOld = null;
        fNew = null;
    }

und mein Actionlistener:

Java:
localPBar.setMaximum(vItemsToCutCopy.size());
                    localPBar.setValue(0);
                    localPBar.setVisible(true);
                    
                    SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>()
                    {
                        protected Void doInBackground()
                        {
                            synchronized (vItemsToCutCopy) 
                            {
                                for(int i = 0; i < vItemsToCutCopy.size(); i++)
                                {
                                    Tree t = (Tree)vItemsToCutCopy.get(i);
                            
                                     File fOld = new File(t.getPath());
                            
                                     if(!fOld.exists())
                                     {
                                         localPBar.setMaximum(localPBar.getMaximum()-1);
                                
                                         continue;
                                     }
                            
                                     File fNew = new File(localPath.getText()+t.getName());
                            
                                     if(localIsCut)
                                     {
                                         fOld.renameTo(fNew);
                                     }else{
                                         try
                                         {
                                             if(fOld.isDirectory())
                                             {
                                                 copyLocalDirectory(fOld,fNew);
                                        
                                                 continue;
                                             }
                                    
                                             FileChannel inChannel = new FileInputStream(fOld).getChannel();
                                             FileChannel outChannel = new FileOutputStream(fNew).getChannel(); 
                                             inChannel.transferTo(0, inChannel.size(), outChannel);
                                    
                                             localPBar.setValue(localPBar.getValue()+1);
                                         }
                                         catch(FileNotFoundException e1){}
                                         catch(IOException e2){}
                                     }    
                                     t = null;
                                     fOld = null;
                                     fNew = null;
                                } 
                          }
                          return null;
                    }

                    protected void done()
                    {
                    }
               };
               worker.execute();

Das Problem ist jetzt noch, dass die JProgressBar (wenn ich Ordner kopiere) sofort auf 100% springt und ca. 5 Sekunden später kann ich im Konsolenfenster beobachten wie die Funktion: copyLocalDirectory immer 1er ausspuckt.

Ich probier das schon den ganzen Abend :mad: Komme bisher leider nicht weiter. Weiß jemand was das Problem ist?

lg
 

KrokoDiehl

Top Contributor
Zunächst einmal würde ich den SwingWorker in eine eigene Klasse machen damit man mehr Übersicht hat, auch auf welche Variablen er zugreift.

Wenn du im SwingWorker (bzw. in irgendeinem Thread außer dem EDT) etwas wie
Java:
localPBar.setMaximum(localPBar.getMaximum()-1);
machst, ist das prinzipiell problematisch, weil es ein Aufruf an Swing ist und der sollte im EDT erfolgen. Das heißt solche Aufrufe entweder im bereits genannten
Code:
SwingUtilities.invokeLater()
verpacken oder den
Code:
publish()
-Mechanismus vom SwingWorker nutzen.

Prinzipiell hat der SwingWorker einen "progress"-Mechanismus, den man über einen PropertyChangeListener abfragen kann. Hier ist das mit dem EDT auch schon automatisch geregelt, sodass man im Minimalfall folgendes machen muss:

Java:
// GUI-Impl:
void onStartBackgroundTask() {
    SwingWorker worker = new MySwingWorker();
    worker.addPropertyChangeListener(new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent event) {
            // diese Event löst der Worker automatisch im EDT aus
            if ("progress".equals( event.getPropertyName )) {

                // man holt sich den aktuellen Fortschritt und setzt seine
                // Fortschrittsleiste entsprechend
                int progress = (int) event.getNewValue();
                myProgressBar.setValue(progress);
            }
        }
    });
    worker.execute();    
}

// swing worker
void doInBackground() {
    setProgress(0); //löst PropertyChangeEvent aus, s.o.
    
    while (blablabla) {
        setProgress( xy );
    }
    ...
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Rekursive Methode JProgressBar AWT, Swing, JavaFX & SWT 4
T JProgressbar während actionListener updaten AWT, Swing, JavaFX & SWT 1
M Swing JProgressbar und Outoputstream probleme AWT, Swing, JavaFX & SWT 2
A Swing JProgressbar im Windows Look & Feel Farbanpassung AWT, Swing, JavaFX & SWT 2
G JProgressBar: Verständnis Problem AWT, Swing, JavaFX & SWT 3
T Swing JProgressBar mit String unschön AWT, Swing, JavaFX & SWT 5
H jprogressbar während datenabfrage anzeigen AWT, Swing, JavaFX & SWT 5
P Problem Thread.sleep() und JProgressBar AWT, Swing, JavaFX & SWT 7
E Swing JProgressBar updaten AWT, Swing, JavaFX & SWT 3
D Swing JProgressBar soll ende erkennen AWT, Swing, JavaFX & SWT 4
V Swing JProgressBar aktualisieren AWT, Swing, JavaFX & SWT 14
M JProgressBar updatet nicht AWT, Swing, JavaFX & SWT 4
T Swing JProgressBar Indeterminate bleibt stehen bei neuem Fenster AWT, Swing, JavaFX & SWT 6
A JProgressBar updaten abhängig vom Output eines externen Skripts AWT, Swing, JavaFX & SWT 2
M JProgressBar für einen Thread AWT, Swing, JavaFX & SWT 14
J JProgressBar Indeterminate AWT, Swing, JavaFX & SWT 17
J JProgressBar Farbverlauf AWT, Swing, JavaFX & SWT 2
O Probleme mit JProgressBar bei der Statusanzeige AWT, Swing, JavaFX & SWT 5
S jProgressbar von einem Download AWT, Swing, JavaFX & SWT 6
C Swing JProgressBar in JDialog wird nicht angezeigt AWT, Swing, JavaFX & SWT 6
S Swing StatusLeiste mit JProgressBar AWT, Swing, JavaFX & SWT 4
S JProgressBar in Abhängigkeit eines FileInputStreams AWT, Swing, JavaFX & SWT 2
S (Applets) JProgressBar wird erst am Ende angezeigt AWT, Swing, JavaFX & SWT 13
S Problem mit JProgressBar AWT, Swing, JavaFX & SWT 3
E Swing DB Zugriff mit JProgressBar?! AWT, Swing, JavaFX & SWT 8
C Swing JProgressBar Aktualisiert sich nicht. AWT, Swing, JavaFX & SWT 9
M JProgressBar Look and Feel AWT, Swing, JavaFX & SWT 5
C JProgressBar und JLabel AWT, Swing, JavaFX & SWT 5
K JProgressBar transparent AWT, Swing, JavaFX & SWT 10
M JProgressBar AWT, Swing, JavaFX & SWT 2
K JProgressBar für Serialisierung AWT, Swing, JavaFX & SWT 6
multiholle [JProgressBar] Raster deaktivieren AWT, Swing, JavaFX & SWT 14
M JProgressBar übereinander legen? AWT, Swing, JavaFX & SWT 3
B JProgressbar wird nicht aktualisert, trotz Threads AWT, Swing, JavaFX & SWT 6
G JProgressBar actionPerformedMethode und SwingUI thread AWT, Swing, JavaFX & SWT 36
S JProgressBar und Threads AWT, Swing, JavaFX & SWT 11
G Repaint bei JProgressBar AWT, Swing, JavaFX & SWT 3
A Richtiger Umgang mit jProgressBar AWT, Swing, JavaFX & SWT 2
H JProgressBar in TableColumn von JTable setzen/abfragen AWT, Swing, JavaFX & SWT 5
B JProgressBar: wie muss ich das lösen? AWT, Swing, JavaFX & SWT 4
R JProgressBar-Verhalten AWT, Swing, JavaFX & SWT 5
G JProgressbar AWT, Swing, JavaFX & SWT 8
A JProgressBar: Farbe im Windows Look&Feel ändern. AWT, Swing, JavaFX & SWT 1
C JProgressBar und ihre Tücken AWT, Swing, JavaFX & SWT 8
G JProgressBar in JTable AWT, Swing, JavaFX & SWT 6
G Probleme mit JProgressbar auf JPanel in JFrame AWT, Swing, JavaFX & SWT 6
F JProgressBar und NullPointerException AWT, Swing, JavaFX & SWT 4
T JProgressBar und CMP Bean AWT, Swing, JavaFX & SWT 2
J JProgressBar flackert AWT, Swing, JavaFX & SWT 14
S JProgressBar zu JOptionPane hinzufügen. AWT, Swing, JavaFX & SWT 8
M Swinganwendung Threads mit JProgressBar AWT, Swing, JavaFX & SWT 7
L JProgressbar möglichst genau AWT, Swing, JavaFX & SWT 3
G JProgressBar + Thread + Client AWT, Swing, JavaFX & SWT 10
R JProgressBar ohne Threads verwenden AWT, Swing, JavaFX & SWT 6
I JProgressBar String anzeigen, danach wieder normale Ansicht AWT, Swing, JavaFX & SWT 3
G JProgressBar AWT, Swing, JavaFX & SWT 8
L JProgressBar wird nicht mehr aktualisiert AWT, Swing, JavaFX & SWT 2
U JProgressBar in umgekehrter Richtung AWT, Swing, JavaFX & SWT 2
S JProgressBar einbinden AWT, Swing, JavaFX & SWT 5
H JProgressBar AWT, Swing, JavaFX & SWT 6
T JProgressBar und JPG AWT, Swing, JavaFX & SWT 2
D Problem mit JProgressBar und Threads AWT, Swing, JavaFX & SWT 7
P Animation läuft nicht korrekt AWT, Swing, JavaFX & SWT 8
CodingBerlin JavaFX Programm läuft nur unter Eclipse AWT, Swing, JavaFX & SWT 1
N Programm Läuft nicht auf anderen Pcs AWT, Swing, JavaFX & SWT 9
MiMa Java und JavaFX 13 läuft endlich AWT, Swing, JavaFX & SWT 4
L JavaFX TreeView aufstellen läuft irgendwie auf Endlosschleife AWT, Swing, JavaFX & SWT 3
O LayoutManager pagelayout - Example läuft einfach nicht ! AWT, Swing, JavaFX & SWT 6
Blender3D Meine Swing Anwendung läuft unter Windows 10 und Ubuntu aber nicht auf Windows 7 AWT, Swing, JavaFX & SWT 16
R Swing Programm läuft nur beim Debuggen korrekt ab AWT, Swing, JavaFX & SWT 4
T swing läuft nur beding flüssig AWT, Swing, JavaFX & SWT 1
J JavaFX Anwendung läuft in eclipse, nicht aber exportiert AWT, Swing, JavaFX & SWT 2
N Programm läuft perfekt in Eclipse aber nicht in .JAR AWT, Swing, JavaFX & SWT 3
P Swing GUI noch nicht gezeichnet - Logik läuft - blockiert AWT, Swing, JavaFX & SWT 3
E Animation läuft nicht mehr flüssig AWT, Swing, JavaFX & SWT 8
P Einfaches GUI läuft nicht AWT, Swing, JavaFX & SWT 6
A AWT Beim (mehrmaligen) Screenshot machen läuft der Speicher voll AWT, Swing, JavaFX & SWT 2
R GUI hängt während Programm läuft AWT, Swing, JavaFX & SWT 7
P repaint während Thread läuft AWT, Swing, JavaFX & SWT 9
G SWT-App läuft nicht unter OSX, unter Win aber problemlos AWT, Swing, JavaFX & SWT 3
G Programm läuft nur auf manchen Rechnern AWT, Swing, JavaFX & SWT 10
O Swing es können keine neuen Labels hinzufügt werden während der Timer läuft AWT, Swing, JavaFX & SWT 14
S Swing Hyperlink mit Hyperlinklistener läuft Amok AWT, Swing, JavaFX & SWT 3
P Swing [gelöst/erledigt] Gleicher Code läuft unterschiedlich unter Linux und Windows AWT, Swing, JavaFX & SWT 5
M Button funktioniert nicht mehr wenn Schleife läuft AWT, Swing, JavaFX & SWT 3
K Mein Informatikprojekt läuft aus dem Ruder Hilfe. F1 ^^ AWT, Swing, JavaFX & SWT 5
D Programm läuft unter XP aber nicht unter Knoppix AWT, Swing, JavaFX & SWT 6
A GtkLookAndFeel - läuft nicht . AWT, Swing, JavaFX & SWT 13
G Wie läuft ein GUI AWT, Swing, JavaFX & SWT 4
P WM 2006 - The Memory Game :P läuft nicht. AWT, Swing, JavaFX & SWT 15
M sicherstellen, dass nur eine Instanz läuft. AWT, Swing, JavaFX & SWT 6
S JCellRenderer läuft nur einmal in bestimmte Bedingung AWT, Swing, JavaFX & SWT 5
richis-fragen Spaltenbreite bei drag nicht änderbar AWT, Swing, JavaFX & SWT 4
Juelin if Abfrage funktioniert nicht richtig AWT, Swing, JavaFX & SWT 10
MiMa Darstellung von FXML ateien nicht korrekt (SceneBuilder) AWT, Swing, JavaFX & SWT 2
P Methode wird nicht überprüft AWT, Swing, JavaFX & SWT 4
C Button ActionListener funktioniert nicht AWT, Swing, JavaFX & SWT 1
M Mandelbrot mit BigDecimal erstellen und in der UI zeichnen, funktionierte nicht. AWT, Swing, JavaFX & SWT 1
H JavaFX PixelWriter.setColor setzt Farbe nicht AWT, Swing, JavaFX & SWT 2
M JavaFX Diagonale Linie nicht ausgegeben/angezeigt AWT, Swing, JavaFX & SWT 1

Ähnliche Java Themen

Neue Themen


Oben