1

I am new to JProgressBar and new to OOPs concepts as well (learning it) and read a lot of articles and tried my best to learn it. All of the examples shown had a button which starts progress in it but how can I make a method so that when the method is called it starts progress?

Here is my code first

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

public class ProgressDemo
{
    JProgressBar ProgressBar;
    Task task;
    boolean done = false;

    class Task extends SwingWorker<Void, Void> 
    {
        @Override
        public Void doInBackground() 
        {
            Random random = new Random();
            int progress = 0;
            setProgress(0);
            while (progress < 100) 
            {
               try 
               {
                    Thread.sleep(random.nextInt(1000));
               } 
               catch (InterruptedException ignore){}
               progress += random.nextInt(10);
               setProgress(Math.min(progress, 100));
            }
            return null;
        }
        @Override
        public void done() 
        {
            done = true;
        }
    }

    public void propertyChange(PropertyChangeEvent evt) 
    {
      if(!done)
      {
        int progress = task.getProgress();
        if(progress==0)
        {
            ProgressBar.setIndeterminate(true);
        }
        else
        {
            ProgressBar.setIndeterminate(false); 
            ProgressBar.setString(null);
            ProgressBar.setValue(progress);
        }
      }
    }

    //I want to make a method here, so that it can be called when ever I want
    public void ExecuteTask()
    {
        task = new Task();
        task.execute();
    }

    public static void main(String[] args) 
    {
        JFrame MainScreen = new JFrame(); 
        JPanel MainPanel = new JPanel();
        ProgressBar = new JProgressBar(0, 100);
        ProgressBar.setValue(0);
        ProgressBar.setStringPainted(false);
        MainPanel.add(ProgressBar);
        MainScreen.getContentPane().add(MainPanel);
        MainScreen.setVisible(true);
    }
}

My jProgressBar is not listening when I call ExecuteTask() method. How can I make it to call ExecuteTask() and it execute task and jProgressBar listen to it?

1 Answers1

2

You never add your PropertyChangeListener to anything, and so since nothing is listening for changes to the SwingWorker, its changes never get transmitted to the JProgressBar. Solution: add the PropertyChangeListener to the SwingWorker after making it. And in fact -- you have no PropertyChangeListener, just a method borrowed from one that you didn't use (??).

Other issues: learn OOPs, at least the rudiments before learning Swing. You should not be using static fields as you're doing here.

Some decent links:


sigh

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;
import java.util.concurrent.ExecutionException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.Timer;

@SuppressWarnings("serial")
public class ProgressDemo extends JPanel {
   private JProgressBar progressBar = new JProgressBar(0, 100);
   private Task task;
   boolean done = false;

   public ProgressDemo() {
      progressBar.setStringPainted(true);
      progressBar.setIndeterminate(true);
      add(progressBar);
   }

   class Task extends SwingWorker<Void, Void> {
      @Override
      public Void doInBackground() {
         Random random = new Random();
         int progress = 0;
         setProgress(0);
         while (progress < 100) {
            try {
               Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException ignore) {
            }
            progress += random.nextInt(10);
            setProgress(Math.min(progress, 100));
         }
         return null;
      }

      @Override
      public void done() {
         done = true;
      }
   }

   private class TaskListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
         if ("progress".equals(evt.getPropertyName())) {
            int progress = task.getProgress();
            progressBar.setIndeterminate(false);
            progressBar.setString(null);
            progressBar.setValue(progress);
         }
         if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
            // always need to know when the SW is done
            // so we can call get() and trap exceptions
            try {
               task.get();
            } catch (InterruptedException | ExecutionException e) {
               e.printStackTrace();
            }
         }
      }
   }

   // I want to make a method here, so that it can be called when ever I want
   public void executeTask() {
      task = new Task();
      task.addPropertyChangeListener(new TaskListener());
      task.execute();
   }

   public static void main(String[] args) {
      JFrame mainScreen = new JFrame();
      mainScreen.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      final ProgressDemo demoPanel = new ProgressDemo();

      mainScreen.getContentPane().add(demoPanel);
      mainScreen.pack();
      mainScreen.setLocationByPlatform(true);
      mainScreen.setVisible(true);

      // just for yucks, let's wait 3 seconds before calling executeTask()
      int delay = 3 * 1000;
      new Timer(delay, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            demoPanel.executeTask();

            // stop timer
            ((Timer) e.getSource()).stop();
         }
      }).start();
   }
}
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373