Création d'une barre de progression à mettre à jour avec les résultats d'une boucle for en java [dupliquer]


Cette question a déjà une réponse ici:

J'ai créé une boucle for qui compte de 0 à 850000. J'ai choisi un nombre élevé parce que je veux créer une barre de progression qui se mettra à jour en utilisant les résultats dans la boucle for. Voici le code que j'ai jusqu'à présent.

public class ProgressBarTest extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {





        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ProgressBarTest frame = new ProgressBarTest();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ProgressBarTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        for(int i = 850000; i>0; i--) {
            System.out.println("i = " + i);
        }

    }

}

Je n'arrive pas à trouver un moyen d'obtenir une barre de progression à mettre à jour en utilisant une boucle for. J'ai créé une barre de progression qui a travaillé sur une minuterie, mais ce n'est pas ce que je veux faire. Je veux essentiellement qu'il soit mis à jour à partir de 0% à 100%. Cela me semble simple, mais je suis coincé dessus depuis un moment. J'apprécie toute sorte d'exemple de code qui m'aidera à comprendre comment cela fonctionne.

Author: David Gardener, 2017-11-20

2 answers

Voici l'exemple complet, en utilisant SwingWorker proposé par le Saran

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;

public class ProgressBarTest extends JFrame {

    private static final long LOOP_LENGTH = 85000000;

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    ProgressBarTest frame = new ProgressBarTest();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ProgressBarTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        JProgressBar progress = new JProgressBar();
        progress.setStringPainted(true);
        contentPane.add(new JLabel("Loop progress is: "), BorderLayout.NORTH);
        contentPane.add(progress, BorderLayout.SOUTH);
        setContentPane(contentPane);
        ProgressWorker worker = new ProgressWorker(progress);
        worker.execute();
    }

    private static class ProgressWorker extends SwingWorker<Void, Integer> {
        private final JProgressBar progress;

        public ProgressWorker(JProgressBar progress) {
            this.progress = progress;
        }

        @Override
        protected Void doInBackground() throws Exception {
            for (long i = LOOP_LENGTH; i > 0; i--) {
                final int progr = (int) ((100L * (LOOP_LENGTH - i)) / LOOP_LENGTH);
                publish(progr);
            }
            return null;
        }

        @Override
        protected void process(List<Integer> chunks) {
            progress.setValue(chunks.get(chunks.size() - 1));
            super.process(chunks);
        }

        @Override
        protected void done() {
            progress.setValue(100);
        }
    }
}
 3
Author: Sergiy Medvynskyy, 2017-11-20 14:56:01

Vous devez utiliser SwingWorker, Lorsqu'un programme Swing doit exécuter une tâche de longue durée, il utilise généralement l'un des threads de travail. Alors, essayez ceci:

public class JProgressBarTest extends SwingWorket<Void,Integer>{

private JProgressBar jpb;
  public ProgrssBarTest(JProgressBar jpb){
    this.jpb = jpb;
  }

  @Override
  protected void process(List<Integer> chunks){
    int i = chunks.get(chunks.size()-1);
    jpb.setValue(i);
  }

  @Override
  protected void doInBackground() throws Exception{
    int x = 0;
    for(int i = 850000; i>0; i--) {
        publish(x); //replace x with the number you want to increment the progressbar each time pubish is called
        x = x + i; //or replace i with the increment you want
        System.out.println("i = " + i);
    }
  }

  @Override
  protected void done(){
    try{
      get();
    }catch(ExecutionException |InterruptedException e){
      ;
    }
  }

}

Dans votre classe, remplacez la boucle en appelant la nouvelle classe de la classe que j'ai écrite ci-dessus et passez-lui un nouveau JProgressBar() et en ajoutant .execute(), comme ceci:

new JProgressBarTest(new JProgressBar()).execute();
 2
Author: Abdane, 2017-12-01 14:10:41