Package jmt.gui.common.panels.parametric

Source Code of jmt.gui.common.panels.parametric.PAProgressWindow$Timer

/**
  * Copyright (C) 2006, Laboratorio di Valutazione delle Prestazioni - Politecnico di Milano

  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.

  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.

  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */

package jmt.gui.common.panels.parametric;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagLayout;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JToolBar;
import javax.swing.border.EmptyBorder;

import jmt.framework.gui.components.JMTDialog;
import jmt.gui.common.CommonConstants;
import jmt.gui.common.definitions.parametric.ParametricAnalysisDefinition;
import jmt.gui.common.resources.JMTImageLoader;
import jmt.gui.common.startScreen.sampleAnimation.SampleQNAnimation;

/**
* <p>Title: Parametric Analysis Progress Window</p>
* <p>Description: This window is shown during parametric analysis</p>
*
* @author Francesco D'Aquino
*         Date: 4-gen-2006
*         Time: 13.53.23
*/
public class PAProgressWindow extends JMTDialog {
  /**
   *
   */
  private static final long serialVersionUID = 1L;
  public static final String RUNNING_MESSAGE = "What-if analysis running, please wait...";
  public static final String ENUMERATION_MESSAGE = "Running simulation";
  public static final String PAUSE_MESSAGE = "Parametric analysis paused...";
  public static final String STOP_MESSAGE = "Parametric analysis stopped";
  //private final double SIMULATION_DURATION_INITIALIZATION = 0;
  private static final double HISTOGRAM_INTERVALS = 10;
  private JButton start, stop, pause;
  private JToolBar toolbar;
  private JProgressBar progressBar;
  private SampleQNAnimation animation;
  private JLabel mainLabel;
  private JLabel stepLabel;
  private JLabel elapsedTimeLabel;
  //private JLabel remainingTimeLabel;

  JLabel stoppedAnimation;

  private int numberOfSimulations;
  private int stepNumber;
  private JPanel globalPanel;
  private JPanel pivotPanel;
  private boolean stopped, paused;
  private String elapsedTimeString;
  private String remainingTimeString;

  private Timer timer;
  //private double MA_cumulativeTime;
  private double[] simulationTimes;
  private double globalCumulativeTime;
  private double globalMeanSimulationTime;
  private double lastSimulationFinishTime;
  private double globalStartTime;

  boolean wasPaused;
  double pauseTime;
  double resumeTime;

  private double elapsedTime;

  public PAProgressWindow(Frame owner, AbstractAction startAction, AbstractAction pauseAction, final AbstractAction stopAction,
      ParametricAnalysisDefinition pad) {
    super(owner, false);
    numberOfSimulations = pad.getNumberOfSteps();
    stepNumber = 1;
    this.getContentPane().setLayout(new BorderLayout());
    this.setTitle("What-if analysis progress");

    globalCumulativeTime = 0;
    globalMeanSimulationTime = 0;

    this.centerWindow(500, 390);

    // Creates bottom toolbar
    toolbar = new JToolBar();
    toolbar.setFloatable(false);
    toolbar.setRollover(true);
    start = new JButton();
    toolbar.add(start);
    pause = new JButton();
    toolbar.add(pause);
    stop = new JButton();
    toolbar.add(stop);

    start.setAction(startAction);
    start.setText("");
    start.setIcon(JMTImageLoader.loadImage("Sim"));
    start.setFocusPainted(false);
    start.setContentAreaFilled(false);
    start.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
    start.setRolloverIcon(JMTImageLoader.loadImage("SimRO"));
    start.setPressedIcon(JMTImageLoader.loadImage("SimP"));
    start.setVisible(true);

    pause.setAction(pauseAction);
    pause.setText("");
    pause.setIcon(JMTImageLoader.loadImage("Pause"));
    pause.setFocusPainted(false);
    pause.setContentAreaFilled(false);
    pause.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
    pause.setRolloverIcon(JMTImageLoader.loadImage("PauseRO"));
    pause.setPressedIcon(JMTImageLoader.loadImage("PauseP"));
    pause.setVisible(true);

    stop.setAction(stopAction);
    stop.setText("");
    stop.setIcon(JMTImageLoader.loadImage("Stop"));
    stop.setFocusPainted(false);
    stop.setContentAreaFilled(false);
    stop.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
    stop.setRolloverIcon(JMTImageLoader.loadImage("StopRO"));
    stop.setPressedIcon(JMTImageLoader.loadImage("StopP"));
    stop.setVisible(true);

    // Adds a progress bar
    progressBar = new JProgressBar();
    progressBar.setStringPainted(true);
    progressBar.setForeground(Color.BLUE);
    toolbar.add(progressBar);

    // Adds toolbar
    this.getContentPane().add(toolbar, BorderLayout.SOUTH);

    //Creates and adds the animation panel
    //animation = new SampleQNAnimation();
    //animation.start();
    pivotPanel = new JPanel(new GridBagLayout());
    //animation.setPreferredSize(new Dimension(200,120));
    //animation.setBackground(new Color(151,151,151));
    stoppedAnimation = new JLabel(JMTImageLoader.loadImage("emptyAnimation"));
    stoppedAnimation.setPreferredSize(new Dimension(200, 120));
    pivotPanel.add(stoppedAnimation);

    //Creates and adds the description label
    JPanel mainLabelPanel = new JPanel();
    mainLabel = new JLabel(CommonConstants.HTML_START + CommonConstants.HTML_FONT_TITLE + RUNNING_MESSAGE + CommonConstants.HTML_FONT_TIT_END
        + CommonConstants.HTML_END);
    mainLabelPanel.add(mainLabel);

    elapsedTimeString = "00m : 00s";
    remainingTimeString = "-- : --";
    elapsedTimeLabel = new JLabel("Elapsed time: " + elapsedTimeString);
    JPanel elapsedTimeLabelPanel = new JPanel();
    elapsedTimeLabelPanel.add(elapsedTimeLabel);
    //remainingTimeLabel = new JLabel("Residual time: " + remainingTimeString);
    JPanel remainingTimeLabelPanel = new JPanel();
    //remainingTimeLabelPanel.add(remainingTimeLabel);
    remainingTimeLabelPanel.setBorder(new EmptyBorder(10, 0, 10, 0));
    JPanel tempPanel = new JPanel(new BorderLayout());
    tempPanel.add(elapsedTimeLabel, BorderLayout.NORTH);
    //tempPanel.add(remainingTimeLabel,BorderLayout.SOUTH);
    JPanel timeLabelPanel = new JPanel();
    timeLabelPanel.add(tempPanel);
    timeLabelPanel.setBorder(new EmptyBorder(10, 0, 0, 0));
    JPanel stepLabelPanel = new JPanel();
    stepLabel = new JLabel(CommonConstants.HTML_START + CommonConstants.HTML_FONT_NORM + ENUMERATION_MESSAGE + " " + stepNumber + " of "
        + this.numberOfSimulations + "..." + CommonConstants.HTML_FONT_NOR_END + CommonConstants.HTML_END);
    stepLabelPanel.add(stepLabel);
    JPanel lowerLabelPanel = new JPanel(new BorderLayout());
    lowerLabelPanel.add(timeLabelPanel, BorderLayout.CENTER);
    lowerLabelPanel.add(stepLabelPanel, BorderLayout.SOUTH);

    mainLabelPanel.setBorder(new EmptyBorder(20, 20, 10, 20));
    stepLabelPanel.setBorder(new EmptyBorder(20, 20, 20, 20));
    JPanel upperPanel = new JPanel(new BorderLayout());
    upperPanel.add(mainLabelPanel, BorderLayout.CENTER);
    //upperPanel.add(timeLabelPanel,BorderLayout.SOUTH);
    globalPanel = new JPanel(new BorderLayout());
    globalPanel.add(upperPanel, BorderLayout.NORTH);
    globalPanel.add(pivotPanel, BorderLayout.CENTER);
    globalPanel.add(lowerLabelPanel, BorderLayout.SOUTH);
    this.getContentPane().add(globalPanel, BorderLayout.CENTER);

    elapsedTime = 0;
  }

  /* (non-Javadoc)
   * @see jmt.framework.gui.components.JMTDialog#canBeClosed()
   */
  @Override
  public boolean canBeClosed() {
    return stopped;
  }

  /* (non-Javadoc)
   * @see jmt.framework.gui.components.JMTDialog#doClose()
   */
  @Override
  protected void doClose() {
    stop.getAction().actionPerformed(null);
  }

  public void initialize(int numberOfStep) {
    simulationTimes = new double[numberOfStep];
    this.numberOfSimulations = numberOfStep;
    progressBar.setMaximum(numberOfSimulations);
  }

  /**
   * Sets the running number of step
   * @param step the step to be run
   */
  public void setStepNumber(int step) {
    stepNumber = step;
    stepLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_NORM + ENUMERATION_MESSAGE + " " + stepNumber + " of "
        + this.numberOfSimulations + "..." + CommonConstants.HTML_FONT_NOR_END + CommonConstants.HTML_END);
    progressBar.setValue(step - 1);
    updateStatistics(step - 1);
  }

  /**
   * Updates the showed elapsed time
   */
  public void updateTime() {
    elapsedTimeString = this.getTimeString((int) elapsedTime);
    elapsedTimeLabel.setText("Elapsed time: " + elapsedTimeString);
  }

  /**
   * This method updates all statistics related stuff. It contains a simple alghorithm to estimate residual execution time
   * @param lastSimulationCompletedIndex the index of the last finished simulation, beggining from 1.
   */
  private void updateStatistics(int lastSimulationCompletedIndex) {
    //it happens only at the beginning of simulation
    if (lastSimulationCompletedIndex == 0) {
      return;
    }

    // INITIALIZATIONS //

    //set the precision of residual time estimation
    double histogramIntervals = HISTOGRAM_INTERVALS;
    double currentTime = (((double) System.currentTimeMillis()) / 1000 - //get time elapsed from start in seconds
    this.globalStartTime);

    double simulationDuration;
    if (!wasPaused) {
      simulationDuration = currentTime - lastSimulationFinishTime; // the duration of the last finished simulation
    } else {
      simulationDuration = currentTime - lastSimulationFinishTime - (resumeTime - pauseTime);
      wasPaused = false;
    }
    lastSimulationFinishTime = currentTime; //set the new last simulation finishing time
    globalCumulativeTime += simulationDuration; //increase the cumulative time
    globalMeanSimulationTime = globalCumulativeTime / lastSimulationCompletedIndex; //the mean duration time

    double min = simulationDuration; //initialization useful for the first simulation finished
    double max = simulationDuration;

    // END INITIALIZATIONS//

    simulationTimes[lastSimulationCompletedIndex - 1] = simulationDuration; //insert last simulation duration into the Vector

    //for cycle used to get minimum and maximum simulaion duration
    for (int i = 0; i < lastSimulationCompletedIndex; i++) {
      if (simulationTimes[i] < min) {
        min = simulationTimes[i];
      }
      if (simulationTimes[i] > max) {
        max = simulationTimes[i];
      }
    }

    int estimatedTime;
    int[] hist; // it's a vector containing the number of simulation with a duration in a certain range.
    // It's like a histogram; the algorithm uses the relative frequencies to estimate the most
    // probable residual time.

    double dispersion = max - min;

    if (dispersion != 0) { // always true except for the first case, or if all of the simulations have the same duration

      double gap = dispersion / histogramIntervals; //the width of a single histogram band
      hist = new int[(int) histogramIntervals];

      // for cycle used to populate the histogram
      for (int i = 0; i < lastSimulationCompletedIndex; i++) {
        double thisValue = simulationTimes[i];
        for (int j = 1; j <= histogramIntervals; j++) {
          if (thisValue <= (min + j * gap)) {
            hist[j - 1]++;
            break;
          }
        }
      }

      double sum = 0;
      for (int i = 0; i < histogramIntervals; i++) {
        sum += ((hist[i])) * (min + (i + 1) * gap - gap / 2); //weighted sum of all simulation durations
      }
      estimatedTime = (int) (sum / (lastSimulationCompletedIndex) * (numberOfSimulations - lastSimulationCompletedIndex));
    } else {
      estimatedTime = (int) (max * numberOfSimulations - lastSimulationCompletedIndex); //or min since they are the same number
    }
    this.remainingTimeString = "Residual time: " + getTimeString(estimatedTime);
    //this.remainingTimeLabel.setText(remainingTimeString);
  }

  /**
   * Used to format a time in seconds to a hh : mm : ss format
   * @param t time in seconds to be formatted
   * @return the formatted time
   */
  private String getTimeString(int t) {
    String timeString;
    int s = (t % 60);
    int m = ((t / 60) % 60);
    int h = ((t / 3600) % 3600);
    if (h == 0) {
      timeString = "";
    } else {
      if (h < 10) {
        timeString = "0" + Integer.toString(h) + "h : ";
      } else {
        timeString = Integer.toString(h) + "h : ";
      }
    }
    if (m < 10) {
      timeString += "0" + Integer.toString(m) + "m : ";
    } else {
      timeString += Integer.toString(m) + "m : ";
    }
    if (s < 10) {
      timeString += "0" + Integer.toString(s) + "s";
    } else {
      timeString += Integer.toString(s) + "s";
    }
    return timeString;
  }

  /**
   * Sets the window in pause state
   */
  public void pause() {
    wasPaused = true;
    pauseTime = ((double) System.currentTimeMillis()) / 1000 - globalStartTime;
    mainLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_TITLE + PAUSE_MESSAGE + CommonConstants.HTML_FONT_TIT_END
        + CommonConstants.HTML_END);
    stopAnimation();
    paused = true;
    stopped = false;
    removeAnimation();
  }

  /**
   * Called to start the progress window
   */
  public void start() {
    globalStartTime = ((double) System.currentTimeMillis()) / 1000;
    lastSimulationFinishTime = 0;
    elapsedTime = 0;
    paused = false;
    stopped = false;
    timer = new Timer();
    timer.start();
    mainLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_TITLE + RUNNING_MESSAGE + CommonConstants.HTML_FONT_TIT_END
        + CommonConstants.HTML_END);
    restoreAnimation();
  }

  /**
   * Called to restart the progress window after it was paused
   */
  public void restart() {
    paused = false;
    stopped = false;
    resumeTime = ((double) System.currentTimeMillis()) / 1000 - globalStartTime;
    timer.setLastTime(resumeTime);
    mainLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_TITLE + RUNNING_MESSAGE + CommonConstants.HTML_FONT_TIT_END
        + CommonConstants.HTML_END);
    restoreAnimation();
  }

  private void removeAnimation() {
    globalPanel.remove(pivotPanel);
    pivotPanel = new JPanel(new GridBagLayout());
    pivotPanel.add(stoppedAnimation);
    globalPanel.add(pivotPanel, BorderLayout.CENTER);
    globalPanel.doLayout();
    globalPanel.validate();
    doLayout();
    validate();
  }

  private void restoreAnimation() {
    globalPanel.remove(pivotPanel);
    animation = new SampleQNAnimation();
    animation.start();
    pivotPanel = new JPanel(new GridBagLayout());
    animation.setPreferredSize(new Dimension(200, 120));
    animation.setBackground(new Color(151, 151, 151));
    pivotPanel.add(animation);
    globalPanel.add(pivotPanel, BorderLayout.CENTER);
    globalPanel.doLayout();
    globalPanel.validate();
    doLayout();
    validate();
  }

  /**
   * Called when simulation is stopped.
   */
  public void stop() {
    paused = false;
    stopped = true;
    mainLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_TITLE + STOP_MESSAGE + CommonConstants.HTML_FONT_TIT_END
        + CommonConstants.HTML_END);
    if (stepNumber > 1) {
      stepLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_NORM + "Only " + (stepNumber - 1) + " simulations of "
          + numberOfSimulations + " were completed " + CommonConstants.HTML_FONT_NOR_END + CommonConstants.HTML_END);
    } else {
      stepLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_NORM + "No simulation was completed "
          + CommonConstants.HTML_FONT_NOR_END + CommonConstants.HTML_END);
    }

    stopAnimation();
    removeAnimation();
    progressBar.setValue(0);
    remainingTimeString = "Residual time: -- : --";
    //remainingTimeLabel.setText(remainingTimeString);
  }

  /**
   * Stops only the animation thread
   */
  public void stopAnimation() {
    animation.stop();
  }

  /**
   * Called when the parametric analyis is finished, not when it is stopped
   */
  public void finished() {
    stopped = true;
    paused = false;
    mainLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_TITLE + "Simulation complete" + CommonConstants.HTML_FONT_TIT_END
        + CommonConstants.HTML_END);
    stepLabel.setText(CommonConstants.HTML_START + CommonConstants.HTML_FONT_NORM + "All of the " + this.numberOfSimulations
        + " simulations were completed" + CommonConstants.HTML_FONT_NOR_END + CommonConstants.HTML_END);

    progressBar.setValue(numberOfSimulations);
    remainingTimeString = "Residual time: -- : --";
    //remainingTimeLabel.setText(remainingTimeString);
    stopAnimation();
    removeAnimation();
  }

  protected class Timer extends Thread {
    double lastTime;

    public Timer() {
      super("Progress timer");
      this.setPriority(Thread.MAX_PRIORITY);
    }

    public void setLastTime(double timeInSec) {
      lastTime = timeInSec;
    }

    @Override
    public void run() {
      lastTime = ((double) System.currentTimeMillis()) / 1000 - globalStartTime;
      while (!stopped) {
        try {
          sleep(1000);
        } catch (InterruptedException ie) {
          JOptionPane.showMessageDialog(null, "Unexpected progress timer termination");
        }
        if (!paused) {
          double time = ((double) System.currentTimeMillis()) / 1000 - globalStartTime;
          elapsedTime += (time - lastTime);
          lastTime = time;
          updateTime();
        }
      }
    }
  }
}
TOP

Related Classes of jmt.gui.common.panels.parametric.PAProgressWindow$Timer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.