code: package wprover;
  
  import UI.EntityButtonUI;
  
  import javax.swing.*;
  import javax.swing.border.EtchedBorder;
  import javax.swing.border.BevelBorder;
  import javax.swing.event.ChangeListener;
  import javax.swing.event.ChangeEvent;
  import java.awt.event.*;
  import java.awt.*;
  import java.net.URL;
  
  
  public class AnimatePanel extends JToolBar implements ActionListener, ChangeListener {
  
      Timer timer;
      JSlider framesPerSecond;
      GExpert expert;
      AnimateC ant;
      JToggleButton bx1, bx2, bx3;
  
                        
                        
      boolean first = true;
      JPanel d;
      drawProcess dp;
      JPopupMenu menu;
  
      public AnimatePanel(GExpert exp, JPanel pn, drawProcess d) {
  
          expert = exp;
          this.d = pn;
          this.dp = d;
  
          this.setOrientation(JToolBar.VERTICAL);
          this.setFloatable(false);
  
          JPanel panel = new JPanel();
          panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
  
          bx1 = makeAButton("play", "play", "start the animation", "Play");
          panel.add(bx1);
  
          bx3 = makeAButton("pause", "pause", "pause the animation", "Pause");
          panel.add(bx3);
  
          bx2 = makeAButton("stop", "stop", "stop the animation", "stop");
          panel.add(bx2);
  
          framesPerSecond = new JSlider(JSlider.HORIZONTAL, 5, 30, 15);
  
          framesPerSecond.setMajorTickSpacing(10);
          framesPerSecond.setPaintTicks(false);
  
          framesPerSecond.setBorder(BorderFactory.createEmptyBorder(0, 0, 1, 0));
          framesPerSecond.addChangeListener(this);
  
  
          int delay = 50;
          timer = new Timer(delay, this);
          timer.setInitialDelay(delay * 7); //We pause animation twice per cycle
          timer.setCoalesce(true);
          this.add(panel);
          this.add(framesPerSecond);
          this.setBorder(BorderFactory.createEtchedBorder()); //Color.lightGray));
  
  
          menu = new JPopupMenu();
          JMenuItem it = new JMenuItem("Close");
          menu.add(it);
          it.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  AnimatePanel.this.setVisible(false);
              }
          });
  
          MouseListener ls = new MouseListener() {
              public void mouseClicked(MouseEvent e) {
                  if (e.getButton() == MouseEvent.BUTTON3) {
                      menu.show((Component) e.getSource(), e.getX(), e.getY());
                  }
              }
  
              public void mousePressed(MouseEvent e) {
              }
  
              public void mouseReleased(MouseEvent e) {
              }
  
              public void mouseEntered(MouseEvent e) {
              }
  
              public void mouseExited(MouseEvent e) {
              }
          };
          bx1.addMouseListener(ls);
          bx2.addMouseListener(ls);
          bx3.addMouseListener(ls);
          framesPerSecond.addMouseListener(ls);
  
          MouseMotionListener ls1 = new MouseMotionListener() {
              public void mouseDragged(MouseEvent e) {
                  if (e.getSource() == framesPerSecond && timer != null) {
                      adjustSpeed();
                  }
              }
  
              public void mouseMoved(MouseEvent e) {
              }
          };
          framesPerSecond.addMouseMotionListener(ls1);
  
      }
  
      public void setEnableAll() {
          bx1.setEnabled(true);
          bx2.setEnabled(true);
          bx3.setEnabled(true);
      }
  
      public Dimension getPreferredSize() {
          return super.getMinimumSize();
      }
  
      public void setAttribute(AnimateC ant) {
          this.ant = ant;
          first = true;
          framesPerSecond.setValue(ant.getInitValue());
      }
  
      public void actionPerformed(ActionEvent e) {
          Object obj = e.getSource();
          String command = e.getActionCommand();
  
          if (obj instanceof Timer)
              ant.onTimer();
  
          else if (command.compareTo("play") == 0) {
              ant.startAnimate();
              timer.start();
          } else if (command.compareTo("stop") == 0) {
              ant.stopAnimate();
              timer.stop();
          } else if (command.compareTo("pause") == 0) {
              if (timer.isRunning())
                  timer.stop();
              else
                  timer.start();
          }
          setStatus();
  
          dp.setCalMode1();
  
          if (!dp.reCalculate()) {
              ant.resetXY();
          }
  
          dp.setCalMode0();
          d.repaint();
      }
  
      public void startA() {
          ant.startAnimate();
          timer.start();
      }
  
      public void stopA() {
          if (timer.isRunning()) {
              if (ant != null) {
                  ant.stopAnimate();
                  dp.reCalculate();
                  dp.stopTrack();
              }
              timer.stop();
          }
      }
  
      public int getSpeed() {
          return 1000 / (int) framesPerSecond.getValue();
      }
  
      public void adjustSpeed() {
          int n = getSpeed();
          ant.Setstep(framesPerSecond.getValue());
          timer.setDelay(n);
      }
  
      public void stateChanged(ChangeEvent e) {
          JSlider source = (JSlider) e.getSource();
  
          if (!source.getValueIsAdjusting()) {
              adjustSpeed();
          }
      }
  
      protected JToggleButton makeAButton(String imageName,
                                          String actionCommand,
                                          String toolTipText,
                                          String altText) {
          String imgLocation = "images/arrow/" + imageName + ".gif";
          URL imageURL = GExpert.class.getResource(imgLocation);
  
          JToggleButton button = new JToggleButton();
          button.setActionCommand(actionCommand);
          button.setToolTipText(toolTipText);
          button.addActionListener(this);
  
          if (imageURL != null) {                      //image found
              button.setIcon(new ImageIcon(imageURL, altText));
          } else {                                     //no image found
              button.setText(altText);
              System.err.println("Resource not found: "
                      + imgLocation);
          }
          button.setUI(new EntityButtonUI());
          return button;
      }
  
      public void setStatus() {
          bx1.setSelected(false);
          bx2.setSelected(false);
          bx3.setSelected(false);
  
          if (timer != null) {
              if (timer.isRunning()) {
                  bx1.setEnabled(false);
                  bx2.setEnabled(true);
                  bx3.setEnabled(true);
              } else {
                  bx1.setEnabled(true);
                  bx2.setEnabled(true);
                  bx3.setEnabled(true);
              }
          }
      }
  
      public void windowOpened(WindowEvent e) {
      }
  
      public void setVisible(boolean aFlag) {
          if (aFlag == false) {
              ant.stopAnimate();
              timer.stop();
              setStatus();
          }
      }
  
      public boolean isRunning() {
          return timer.isRunning();
      }
  
  }
  