code: package wprover;
  
  import UI.GifEncoder;
  
  import javax.swing.*;
  import javax.swing.event.ChangeEvent;
  import javax.swing.event.ChangeListener;
  import java.awt.*;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.image.BufferedImage;
  import java.util.Vector;
  
  /**
   * Created by IntelliJ IDEA.
   * User: ye
   * Date: 2008-6-26
   * Time: 16:18:09
   * To change this template use File | Settings | File Templates.
   */
  public class ImageTimer extends JBaseDialog implements ActionListener, ChangeListener {
      private GExpert gxInstance;
      private JLabel label1, label2;
      private Timer timer;
      private Rectangle rc;
      private CProveBarPanel bar;
      private GifEncoder encorder;
      private int delay, delay1, delay2;
      private int nf = 0;
      private JSlider slider, slider1, slider2;
      private JTextField field, field1, field2;
      private Thread sprocess;
      private boolean result = false;
      private boolean interrupted = false;
      private boolean finished = false;
  
  
      BufferedImage[] nimage = new BufferedImage[1000];
      int n1 = 0;
      int n2 = 0;
  
      public boolean getResult() {
          return result;
      }
  
      public void stateChanged(ChangeEvent e) {
          int n = slider.getValue();
          delay = n;
          delay1 = slider1.getValue();
          delay2 = slider2.getValue();
          updateValue();
      }
  
  
      public ImageTimer(GExpert f) {
          super(f.getFrame(), "Saving Proof as GIF File", true);
          gxInstance = f;
          nf = 0;
          n1 = 0;
          n2 = -1;
  
          JPanel p = new JPanel();
          p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
          JPanel pp = new JPanel();
          pp.setLayout(new BoxLayout(pp, BoxLayout.X_AXIS));
          pp.setBorder(BorderFactory.createEmptyBorder(3, 13, 3, 13));
  
          JPanel p2 = new JPanel();
          p2.setLayout(new GridLayout(3, 1));
          p2.setBorder(BorderFactory.createEmptyBorder(3, 13, 3, 13));
          p2.add(new JLabel("Defaut Delay"));
          p2.add(new JLabel("Delay at Begin"));
          p2.add(new JLabel("Delay at End"));
          pp.add(p2);
  
          p2 = new JPanel();
          p2.setLayout(new GridLayout(3, 1));
          p2.setBorder(BorderFactory.createEmptyBorder(3, 13, 3, 13));
  
          slider = new JSlider(0, 1500, 200);
          slider1 = new JSlider(0, 15000, 500);
          slider2 = new JSlider(0, 15000, 500);
          slider.setMinorTickSpacing(50);
          slider1.setMinorTickSpacing(200);
          slider2.setMinorTickSpacing(200);
  
          slider.addChangeListener(this);
          slider1.addChangeListener(this);
          slider2.addChangeListener(this);
          p2.add(slider);
          p2.add(slider1);
          p2.add(slider2);
          pp.add(p2);
  
          p2 = new JPanel();
          p2.setLayout(new GridLayout(3, 1));
          p2.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
          field = new JTextField("1111111");
          field1 = new JTextField("1111111");
          field2 = new JTextField("1111111");
          p2.add(field);
          p2.add(field1);
          p2.add(field2);
          field.setEditable(false);
          field1.setEditable(false);
          field2.setEditable(false);
  
          pp.add(p2);
          p.add(pp);
  
  
          label1 = new JLabel("0 frame(s) added");
          p.add(label1);
  
  
          JPanel p3 = new JPanel();
          p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
          p3.add(Box.createHorizontalGlue());
          JButton bok = new JButton("Start");
          JButton bcancel = new JButton("Cancel");
          bok.addActionListener(this);
          bcancel.addActionListener(this);
          p3.add(bok);
          p3.add(bcancel);
          p.add(p3);
  
  
          this.getContentPane().add(p);
          pack();
          f.centerDialog(this);
  
      }
  
  
      public void setDelay(int n) {
          delay = n;
          slider.setValue(n);
          slider1.setValue(n * 2);
          slider2.setValue(n * 3);
      }
  
  
      public void updateValue() {
          int n = slider.getValue() / 100;
          int n1 = slider1.getValue() / 100;
          int n2 = slider2.getValue() / 100;
          field.setText(Double.toString(n / 10.00));
          field1.setText(Double.toString(n1 / 10.00));
          field2.setText(Double.toString(n2 / 10.00));
      }
  
      public void setEncorder(GifEncoder e) {
          this.encorder = e;
      }
  
      public void setProveBar(CProveBarPanel bar) {
          this.bar = bar;
      }
  
      public void setRectangle(Rectangle rc) {
          this.rc = rc;
      }
  
      public void start() {
          if (timer == null)
              timer = new Timer(delay, this);
          timer.start();
          bar.AStep();
          startSave();
      }
  
      public void startSave() {
          if (sprocess == null) {
              sprocess = new Thread(new SaveProcess());
              sprocess.start();
          } else if (!sprocess.isAlive()) {
              if (!running) {
                  sprocess = new Thread(new SaveProcess());
                  sprocess.start();
              }
          }
      }
  
      public void imageAdded() {
          BufferedImage i = gxInstance.getBufferedImage2(rc);
          if (i != null) {
              n2++;
              nimage[n2] = i;
              nf++;
              label1.setText(nf + " frame(s) added");
          }
      }
  
      public void actionPerformed(ActionEvent e) {
          Object o = e.getSource();
  
          if (o == timer) {
              if (n1 > n2) {
                  imageAdded();
                  startSave();
              }
              if (gxInstance.dp.all_flash_finished()) {
                  if (bar.isStepAtEnd()) {
                      timer.stop();
                      finished = true;
  //                    this.setVisible(false);
                      result = true;
                  } else
                      bar.AStep();
              }
          } else {
              String s = e.getActionCommand();
              if (s.equalsIgnoreCase("Start")) {
                  this.start();
                  JButton b = (JButton) e.getSource();
                  b.setEnabled(false);
                  slider.setEnabled(false);
                  slider1.setEnabled(false);
                  slider2.setEnabled(false);
              } else {
                  if (timer != null) {
                      timer.stop();
                      bar.stop();
                      interrupted = true;
  
                  } else {
                      interrupted = true;
                      this.setVisible(false);
                  }
              }
          }
      }
  
  
      boolean running = false;
  
      class SaveProcess implements Runnable {
  
          public SaveProcess() {
              running = false;
          }
  
          public void run() {
              running = true;
              if (nimage[n1] != null) {
                  while (nimage[n1] != null) {
                      if (n1 == 0)
                          encorder.setDelay(delay1);
                      else if (finished && nimage[n1 + 1] == null)
                          encorder.setDelay(delay2);
                      else encorder.setDelay(delay);
  
                      BufferedImage a = nimage[n1];
                      encorder.addFrame(a);
                      nimage[n1] = null;
                      n1++;
                  }
              }
  
              if (interrupted) {
                  result = false;
                  ImageTimer.this.setVisible(false);
              }
              if (finished) {
                  result = true;
                  ImageTimer.this.setVisible(false);
              }
              running = false;
          }
  
  
      }
  }
  