Event Handling Thread - Abruf der get-Methode

Hein_nieH

Bekanntes Mitglied
Hallo Freunde der Bits und Bytes,

ich benötige einmal Hilfe beim Thema Threads.
Um mein Problem darzustellen habe ich ein Beispielprogramm (Quelle D.Louis, Buch Java 7) etwas abgewandelt.

Mein Ziel ist, dass ich in einer Berechnungsklasse den Progressbar anzeige und nach der Berechnung aus der Klasse die Ergebnisse abrufen kann.

Das Problem liegt für mich in der Klasse Lauscher bei folgendem Konstrukt:
Java:
            while ( thread.isAlive() )
            {}

Lasse ich das Konstrukt weg, dann funktioniert der Progressbar aber action.getString() liefert das Ergebnis vor der Berechnung (for next Schleife) . Das Ergebnis sollte lauten "Test99".
Entferne ich das Konstrukt, dann erhalte ich das Ergebnis aus der Lauscher-Klasse wie gewünscht, aber der Progressbar funktioniert nicht mehr.

Wie müsste ich meinen Code ändern, damit der Progressbar funktioniert und die Werte nach dem abarbeiten der Berechnung/Schleife angezeigt werden?

Vielleicht kann mir jemand helfen.
Gruss Hein_nieH

Hier mein Code
Java:
/**
* JProgressBarDemo - Fortschrittsanzeige
*/
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;

public class JProgressBarDemo  extends JFrame 
{
    private JButton button1;
    private JButton button2;
    private JLabel label;
    private JProgressBar progressBar;
    private JPanel progressBarPanel;
  
    public static void main(String[] args)
    {
        JProgressBarDemo prgTest = new JProgressBarDemo();
      
        prgTest.setVisible(true);
    }
  
    public JProgressBarDemo()
    {
        setTitle("JProgressBar-Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(300,200));
        JPanel panel2 = new JPanel();
        button1 = new JButton("Von 0 bis 100");
        button1.addActionListener( new Lauscher() );
        button2 = new JButton("Unbestimmt");
        button2.addActionListener( new Lauscher() );
      
        panel2.add(button1);
        panel2.add(button2);
      
        JPanel panel3 = new JPanel();
        label=new JLabel();
        panel3.add(label);
      
        progressBarPanel = new JPanel();
        getContentPane().add(progressBarPanel,  BorderLayout.CENTER);
        getContentPane().add(panel2, BorderLayout.NORTH);
        getContentPane().add(panel3, BorderLayout.SOUTH);
    }
  
    class Lauscher implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            JButton quelle = (JButton) e.getSource();
          
            // Schalter deaktivieren
            button1.setEnabled(false);
            button2.setEnabled(false);
          
            //im Event-Thread
            boolean unbestimmt = (quelle == button2);
            progressBar = new JProgressBar();
            progressBar.setStringPainted(true);
          
            progressBar.setIndeterminate(unbestimmt);
            progressBar.setStringPainted(!unbestimmt);
            progressBarPanel.add(progressBar);
            revalidate();
          
          
            ActionClass action = new ActionClass();
            Thread thread = new Thread( action );
            thread.start();
          
            //Bei thread.isAlive() wird kein Progress angezeigt!!!
            while ( thread.isAlive() )
            {}
          
            label.setText( action.getString() );
          
        }//actionPerformed
    }//Lauscher
  
    class ActionClass implements Runnable
    {
        private String strBack = "xxxxx";
      
        public String getString()
        {
            return this.strBack;
        }
      
        public void run()
        {
          
            for(int i = 0; i < 100; i++)
            {
                try
                {
                    // hier wird gearbeitet und die Fortschrittsanzeige aktualisiert
                    final int fortschritt = i;
                    SwingUtilities.invokeLater(new Runnable()
                    {
                        public void run()
                        {
                            progressBar.setValue(fortschritt);
                        }
                    });//new Runnable()
                  
                    strBack="Test" + i ; //sinnfrei nur für Test
                  
                    Thread.sleep(100);
                }
                catch(Exception ex)
                {
                    System.out.println( ex.getMessage() );
                }//catch
            }//for
          
      
            // Schalter deaktivieren
            button1.setEnabled(true);
            button2.setEnabled(true);
      
            progressBar.setVisible(false);
            progressBarPanel.remove(progressBar);
            revalidate();
        }//run
    }//class

}//class
 
Also diese ActionListener arbeiten im Event Dispatch Thread - in dem darfst Du natürlich nicht in einer Schleife aktiv warten!

Warum packst Du bei dir nach der Berechnung nicht eine entsprechenden Aufruf ein, sprich: Da wo Du die Buttons wieder aktivierst und so kannst Du dann auch das Label setzen.

Wobei das auch eigentlich in einem SwingUtilities.invokeLater sein sollte, denn Du bist ja noch im Thread und du willst Veränderungen an der UI nur im EDT machen!
 
Hallo,

ich habe bis jetzt verschiedene Versuche unternommen. Lieder ist mir noch nichts verwertbares eingefallen.
@kneitzel: Die Lösung scheint mir nach meinen missglückten Versuchen dann doch logisch.
ich werde berichten.

Gruss Hein_nieH
 
Moinsen,

Problem gelöst. Mein Gedankengang war suboptimal 😕.
Mit einem SwingWorker lässt sich das eingangs beschriebene Problem gut lösen.

Gruss Hein_nieH
 
Du solltest dir ein aktuelleres Buch besorgen, grad wenn es um tiefergehende Konzerte geht, hat sich innerhalb des letzten Jahrzehnts doch ein bisschen was getan...
Aber nicht an AWT/Swing, das ist noch genauso aktuell wie damals... 🙈

Aber ist schon recht: Listener und via Lambdas oder Method-References machen den Code schon um einiges schöner!
 

Neue Themen


Zurück
Oben