2017-02-19 3 views
-2

Ich habe Code mit Swing-Libs geschrieben, dass, wenn ein Actionlistener hinzugefügt wird, eine Fortschrittsbalken nicht aktualisiert wird.Java Swing ProgressBar

Ohne einen Knopf und Aktion Hörer, funktioniert es gut. Wie erzwinge ich ein progressBar Update so einfach und sauber wie möglich? Angehängter Code ist ein leicht verständliches Beispiel, das mein Problem zusammenfasst. Wenn Sie eine ActionPerformed-Methode auskommentieren und das Programm von main aus ausführen, funktioniert das problemlos.

Fügen Sie nicht einfach den Code ohne Erklärung ein.

ps .: ich das gesehen habe: swing progressBar threading

public class Okno { 

    private JProgressBar progressBar = new JProgressBar(0,306); 
    JFrame f = new JFrame("JProgressBar Sample"); 
    JButton b = new JButton("start"); 
    ActionListener a = new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      barupdate(); 
     } 
    }; 


    private void barupdate(){ 
     for(int p = 1; p<308;p=p+2){ 
      System.out.println(p); 

      progressBar.setValue(p); 

       try { 
         Thread.sleep(50); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
     } 
} 

private Okno(){ 

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    progressBar.setStringPainted(true); 

    f.add(progressBar, BorderLayout.SOUTH); 
    f.add(b, BorderLayout.NORTH); 
    b.addActionListener(a); 
    f.setSize(300, 300); 
    f.setVisible(true); 

} 

public static void main(String[] args) { 
    Okno okno = new Okno(); 
} 
} 
+0

Dies ist ein sehr häufiges Problem, das in der Regel auf die gleiche Weise gelöst wird, die beste Lösung in diesem Fall ist normalerweise einen 'SwingWorker' zu verwenden, [zum Beispiel] (http://stackoverflow.com/questions/12020949/jprogressbar-isnt -progressing/12021971 # 12021971). Sie können sich auch [Concurrency in Swing] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) für weitere Details zu diesem Problem ansehen. In den meisten Fällen ist die Verwendung eines anderen 'Threads' an sich nicht die beste Wahl, da Swing nicht threadsicher ist und Sie zusätzliche Vorkehrungen treffen müssen, um die Benutzeroberfläche zu aktualisieren, die' SwingWorker' Ihnen kostenlos zur Verfügung stellt;) – MadProgrammer

+0

@ MadProgrammer, 'die beste Lösung in diesem Fall ist normalerweise mit einem SwingWorker ... wyou sollte sich Concurrency in Swing ansehen,' - wünschte, ich hätte daran gedacht. – camickr

+0

@camickr Die Frage sollte geschlossen werden, aber ich weiß, dass Sie Probleme mit Leuten haben, die das tun, also ließ ich meinen Kommentar (unterstützt von Ihnen beantwortet) und verließ – MadProgrammer

Antwort

1

Das Problem ist, dass Sie eine Schleife, wo Sie den Fortschrittsbalken Einstellung anpassen, die von einer Aktion Hörer aufgerufen wird. Das Problem ist, die Leiste wird nicht aktualisiert, bis der Hörer fertig ist. Und so erhalten Sie keine Updates. Nicht nur das, aber Sie werden die GUI verunstalten, weil das Fenster nicht auf Mausklicks etc. reagieren kann, während Sie sich in diesem Aktionslistener befinden.

Der beste Weg, dies zu bewältigen, ist stattdessen, einen Swing-Timer im Action-Listener zu erstellen und den Code zum Aktualisieren der Schaltfläche dort zu platzieren und den Timer im Aktions-Listener zu starten.

Der Timer sollte die Leiste nur einmal aktualisieren. und Sie sollten die Tatsache zulassen, dass der Swing-Timer mehrmals aufgerufen wird, um den Teil der Wiederholbarkeit zu spielen. Sie möchten also keine Schleifen in Ihrem Code haben.

+0

danke für das Zeigen mir in eine Richtung ... ich werde berichten, wie es ging und Postleitzahl –

0
Thread.sleep(50); 

Verwenden Sie nicht Thread.sleep (...). Dies verhindert, dass sich die GUI selbst neu erstellt, bis die Schleife beendet ist.

Stattdessen können Sie eine SwingWorker verwenden.

Lesen Sie den Abschnitt aus dem Swing-Tutorial auf Concurrency in Swing, der weitere Informationen enthält und ein Arbeitsbeispiel mit einem SwingWorker enthält.

Schauen Sie sich auch das Inhaltsverzeichnis des Tutorials an. Es gibt einen Abschnitt über How to Use ProgressBars, der auch ein Arbeitsbeispiel enthält. Das Tutorial ist der erste Ort, um nach Beispielen zu suchen.

+0

Code ist ein Beispiel, das mein Problem zusammenfasst, und Sleep() -Methode gibt es nur, um Fortschritte auf einem Progress Bar langsamer zu machen. Wenn Sie den Action-Listening-Code entfernen und den Fortschrittsbalkencode von main aus starten, funktioniert das problemlos. –

+0

Ich weiß. Wenn Sie den Fortschrittsbalken von main() starten, wird der Code in einem anderen Thread ausgeführt. Wenn Sie den Fortschrittsbalken im ActionListener starten, wird der Code auf dem 'Event Dispatch Thread (EDT) 'ausgeführt, welcher der Thread ist, der die GUI ausgibt. Sie müssen also Ihre Fortschrittsleiste in einem separaten Thread starten, weshalb Sie das Tutorial lesen müssen, um besser zu verstehen, wie Swing funktioniert. 'Das Tutorial hat Arbeitsbeispiele'. – camickr