Progess Bar um Ladestatus anzuzeigen

jorgeHX

Erfahrenes Mitglied
Hallo zusammen,
ich versuche gerade ne ProgessBar einzublenden, wenn das Programm für längere Zeit arbeiten muss. Dafür hab ich mir folgendes überleget gehabt:

Code:
public class FortschrittsDialog extends JDialog implements Runnable
{

        private int fortschritt;
        private JLabel statusLbl;
        private String statusTxt;
        private JProgressBar fsbalken; 

        public FortschrittsDialog(Frame fr, String titel)
        {
                super(fr,titel,false);
                this.fortschritt=10;
                this.statusTxt="Bitte warten...";
                this.statusLbl=new JLabel("");
                initDialog();
        }

        public void initDialog()
        {
                // Initialisiere den Fortschrittsbalken
                this.fsbalken = new JProgressBar();
                this.fsbalken.setValue(0);
                
                this.statusLbl.setText(this.statusTxt);

                // 
                JPanel p = new JPanel(new BorderLayout());
                p.setLayout(new BorderLayout());
                p.add(statusLbl,BorderLayout.NORTH);
                p.add(fsbalken,BorderLayout.CENTER);
                getRootPane().add(p);
                //
                setSize(350,100);

                // 
                setResizable(false);

                //
                setVisible(true);
        }


        public void setFortschritt(int f)
        {
                this.fortschritt=f;
        }

        public void setStatusTxt(String s)
        {
                this.statusTxt=s;
        }

        /* (non-Javadoc)
         * @see java.lang.Runnable#run()
         */
        public void run()
        {
                // TODO Auto-generated method stub
                while (true)
                {
                        this.fsbalken.setValue(this.fortschritt);
                        this.statusLbl.setText(this.statusTxt);

                        try
                        {
                                Thread.sleep(300);
                        } catch (InterruptedException e)
                        {
                                // ...
                        }
                }
        }

}

Frage ist, ob der Ansatz richtig ist und wie ich das ganze jetzt richtig zum Laufen bekomme. Momentan scheint es so, als würde run() nie ausgeführt.
Kann mir jemand weiterhelfen?
Danke
 
Hallo,

run wird nicht ausgeführt, weil du keinen neuen Thread startest, dafür bräuchtest du
Code:
new FortschrittsDialog().start();
eigentlich brauchst du aber keinen Thread, du kannst die Werte direkt in den Funktionen setzen lassen:
Code:
public void setFortschritt(int f)
{
    fsbalken.setValue(f);
}
public void setStatusTxt(String s)
{
    statusLbl.setText(s);
}
 
Hallo,
verstehe ich nicht ganz.

Ich will quasi meine Klasse "Fortschritt" aufrufen, wenn eine bestimmte Methode im Programm aufgerufen wird, die ziemlich viel Zeit in Anspruch nimmt.

Wie kann ich denn dann den JDialog zum Progress richtig anzeigen?

Momentan erscheint nur eine 350*100 große Box mit grauem Inhalt.

Hast du ne Idee oder Beispiel?
Danke vielmals
 
Hallo,

das schwierigste bei Progress Balken ist eigentlich das Aktualisieren des Fortschritts, bzw. zu entscheiden, wann und wie oft man den Balken updatet, wenn man nicht weiss, wie lang der Prozess dauern kann. In den meisten Fällen ist der Progress "gefaked". In dem Beispiel unten habe ich den ProgressBar in einer Endlosschleife, also wenn der Progress 100% erreicht, springt es wieder auf 0. Ist zwar nicht besonders elegant, ist aber meistens die einfachste Lösung:
Java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

/**
 * The Class ProgressDialogTest.
 */
public class ProgressDialogTest extends JFrame {

    /**
     * Create a new instance of <code>ProgressDialogTest</code>.
     */
    public ProgressDialogTest() {
        super("ProgressDialogTest");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        final JButton buttonShowProgress = new JButton("Show progress dialog");
        buttonShowProgress.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                final ProgressDialog progressDialog =
                    new ProgressDialog(ProgressDialogTest.this);
                progressDialog.setVisible(true);
            }
        });
        final JPanel panel = new JPanel();
        panel.add(buttonShowProgress);
        getContentPane().add(panel, BorderLayout.NORTH);
    }

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String[] args) {
        final JFrame frame = new ProgressDialogTest();
        final Dimension frameSize = new Dimension(600, 400);
        frame.setSize(frameSize);
        final Dimension screenSize =
            Toolkit.getDefaultToolkit().getScreenSize();
        final int frameX = (screenSize.width - frameSize.width) / 2;
        final int frameY = (screenSize.height - frameSize.height) / 2;
        frame.setLocation(frameX, frameY);
        frame.setVisible(true);
    }

    /**
     * The Class ProgressDialog.
     */
    class ProgressDialog extends JDialog {
        private JProgressBar progressBar;

        /**
         * Instantiates a new progress dialog.
         *
         * @param owner the owner frame
         */
        public ProgressDialog(final JFrame owner) {
            super(owner);
            setTitle("Bitte warten...");
            setSize(350, 100);
            setLocationRelativeTo(owner);
            progressBar = new JProgressBar();
            progressBar.setPreferredSize(new Dimension(300, 16));
            final JPanel panel = new JPanel();
            panel.add(progressBar);
            getContentPane().add(panel, BorderLayout.CENTER);

            startProgress();
        }

        /**
         * Start progress.
         */
        private void startProgress() {
            final int max = progressBar.getMaximum();
            final Thread progress = new Thread(new Runnable() {
                public void run() {
                    int value = progressBar.getValue();
                    while (true) {
                        if (value >= max) {
                            value = 0;
                        }
                        progressBar.setValue(value++);
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                        }
                    }
                }
            });
            progress.start();
        }
    }
}
Wenn Dein Prozess fertig ist, kannst Du den Dialog einfach schliessen (wenn nicht modal).

Grüße
Vincent
 
Hi Vincent,
genau das habe ich gesucht.

Läuft bei mir auch ohne Probleme, nur wenn ich es versuche in mein Programm zu integrieren, wird noch immer ein graues JDialog Feld angezeigt.

Ich habe quasi ein JDialog geöffnet, das den Button XY hat. Sobald ich auf den Button XY klicke, soll sich das ProgressDialogFenster öffnen. Parallel werden Daten in die DB geschrieben und anschließend wird das gesamte Programm geschlossen.

Ich kann machen was ich will, aber irgendwie wird die ProgressBar nicht angezeigt.
Im Debugger habe ich gesehen, dass run mehrmals angesprochen wird. Es liegt irgendwie an der GUI-Anzeige, glaub ich.

Weißt du Rat?

Schon jetzt danke
 
Hallo,

ohne den kompletten Code zu sehen, ist es schwierig, den Fehler zu finden... Vielleicht stimmt was mit dem Layout nicht, wenn der ProgressBar nicht angezeigt wird? Versuche einfach beim Initialiesieren vom Progress-Balken gleich einen Wert zu setzen, um zu sehen, ob der Balken generell nicht angezeigt nicht oder ob's am Thread liegt:
Java:
...
progressBar.setValue(50);
...

Grüße
Vincent
 
Hi Vincent,
also selbst wenn ich das auf 50 setze wird nicht angezeigt. Irgendwas stimmt mit dem Layout nicht.
Aber siehst du einen Fehler in meinen Code?

Aus einer Klasse die von JPanel erbt, rufe ich folgende Methode bei Klick auf einen Button auf

Code:
public void actionPerformed(ActionEvent e) {

    try {
      if (e.getSource() == ok_bt) {

        FortschrittsDialog progressDialog =
                    new FortschrittsDialog(parent);
        progressDialog.setVisible(true);

        bearbeiteMappe();  // längerer Arbeitsschritt für den die ProgressBar bestimmt ist
      }
      else if (e.getSource() == abbrechen_bt) {
        dialog.dispose();
      }
    }
    catch (Exception ex) {}
  }


Code:
import java.awt.BorderLayout;
import java.awt.Frame;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JFrame;
import java.awt.Dimension;


public class FortschrittsDialog extends JDialog
{

  private int fortschritt;
        private JProgressBar fsbalken;

     /**
      * Instantiates a new progress dialog.
      *
      * @param owner the owner frame
      */
     public FortschrittsDialog(final JFrame owner) {
         super(owner);

         this.setBounds(0,0,350,100);
         this.setLayout(new BorderLayout());
   
                setLocationRelativeTo(owner);
                fsbalken = new JProgressBar();
                fsbalken.setPreferredSize(new Dimension(300, 16));
                fsbalken.setValue(50);
                final JPanel panel = new JPanel();
                panel.setLayout(new BorderLayout());
                panel.add(fsbalken, BorderLayout.CENTER);

                this.add(panel, BorderLayout.CENTER);

         startProgress();
     }

     /**
      * Start progress.
      */
     private void startProgress() {
         final int max = fsbalken.getMaximum();
         final Thread progress = new Thread(new Runnable() {
             public void run() {
                 int value = fsbalken.getValue();
                 while (true) {
                     if (value >= max) {
                         value = 0;
                     }
                     fsbalken.setValue(value++);
                     try {
                         Thread.sleep(100);
                     } catch (InterruptedException e) {
                     }
                 }
             }
         });
         progress.start();

     }

     public void stopProgress(){


     }

}

Vielen Dank für die Mühen schon jetzt.
Grüße
 
Hm, also wenn ich Deinen Code ausführe, bekomme ich alles zu sehen. Sorry, aber ich kann in dem Code keinen Fehler finden.

Grüße
Vincent
 
Zurück