/**
   @version 1.03 2004-08-22
   @author Cay Horstmann
*/

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.Timer;

/**
   Program demonstrujący zastosowanie paska postępu
   do monitorowania postępu wykonania wątku.
*/
public class ProgressBarTest
{  
   public static void main(String[] args)
   {  
      JFrame frame = new ProgressBarFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);      
   }
}

/**
   Ramka zawierająca przycisk uruchamiający
   symulację czasochłonnej operacji oraz pasek postępu
   i pole tekstowe.
*/
class ProgressBarFrame extends JFrame
{  
   public ProgressBarFrame()
   {  
      setTitle("ProgressBarTest");
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

      // pole tekstowe, w którym prezentowane jest działanie wątku
      textArea = new JTextArea();

      // panel zawierający przycisk i pasek postępu

      JPanel panel = new JPanel();
      startButton = new JButton("Start");
      progressBar = new JProgressBar();
      progressBar.setStringPainted(true);
      panel.add(startButton);
      panel.add(progressBar);

      checkBox = new JCheckBox("indeterminate");
      checkBox.addActionListener(new 
         ActionListener()
         {  
            public void actionPerformed(ActionEvent event)
            {  
               progressBar.setIndeterminate(checkBox.isSelected());
            }
         });
      panel.add(checkBox);
      add(new JScrollPane(textArea), BorderLayout.CENTER);
      add(panel, BorderLayout.SOUTH); 

      // dodanie akcji dla przycisku

      startButton.addActionListener(new 
         ActionListener()
         {  
            public void actionPerformed(ActionEvent event)
            {  
               progressBar.setMaximum(1000);
               activity = new SimulatedActivity(1000);
               new Thread(activity).start();
               activityMonitor.start();
               startButton.setEnabled(false);
            }
         });


      // dodanie akcji dla licznika czasu
      activityMonitor = new Timer(500, new 
         ActionListener()
         {  
            public void actionPerformed(ActionEvent event)
            {  
               int current = activity.getCurrent();
               
               // pokazuje postęp
               textArea.append(current + "\n");
               progressBar.setStringPainted(!progressBar.isIndeterminate());
               progressBar.setValue(current);
               
               // sprawdza, czy wątek zakończył działanie
               if (current == activity.getTarget())
               {  
                  activityMonitor.stop();
                  startButton.setEnabled(true);
               }
            }
         });
   }

   private Timer activityMonitor;
   private JButton startButton;
   private JProgressBar progressBar;
   private JCheckBox checkBox;
   private JTextArea textArea;
   private SimulatedActivity activity;

   public static final int DEFAULT_WIDTH = 400;
   public static final int DEFAULT_HEIGHT = 200;
}

/**
   Klasa symulująca czasochłonną operację.
*/
class SimulatedActivity implements Runnable
{ 
   /**
      Tworzy obiekt symulowanej operacji. Zwiększa on wartość licznika
      do momentu osiągnięcia wartości docelowej.
      @param t wartość docelowa licznika.
   */
   public SimulatedActivity(int t)
   {  
      current = 0;
      target = t;
   }

   public int getTarget()
   {  
      return target;
   }

   public int getCurrent()
   {  
      return current;
   }

   public void run()
   {  
      try
      {
         while (current < target)
         {    
            Thread.sleep(100);
            current++;
         }
      }
      catch(InterruptedException e)
      {  
      }
   }

   private volatile int current;
   private int target;
}
