mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			461 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			461 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
/* ProgressMonitor.java --
 | 
						|
   Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath 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, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
package javax.swing;
 | 
						|
 | 
						|
import java.awt.Component;
 | 
						|
import java.awt.event.ActionEvent;
 | 
						|
import java.awt.event.ActionListener;
 | 
						|
 | 
						|
import javax.accessibility.AccessibleContext;
 | 
						|
 | 
						|
/**
 | 
						|
 * <p>Using this class you can easily monitor tasks where you cannot
 | 
						|
 * estimate the duration exactly.</p>
 | 
						|
 *
 | 
						|
 * <p>A ProgressMonitor instance waits until the first time setProgress
 | 
						|
 * is called. When <code>millisToDecideToPopup</code> time elapsed the
 | 
						|
 * instance estimates the duration until the whole operation is completed.
 | 
						|
 * If this duration exceeds <code>millisToPopup</code> a non-modal dialog
 | 
						|
 * with a message and a progress bar is shown.</p>
 | 
						|
 *
 | 
						|
 * <p>The value of <code>millisToDecideToPopup</code> defaults to
 | 
						|
 * <code>500</code> and <code>millisToPopup</code> to
 | 
						|
 * <code>2000</code>.</p>
 | 
						|
 *
 | 
						|
 * @author Andrew Selkirk
 | 
						|
 * @author Robert Schuster (robertschuster@fsfe.org)
 | 
						|
 * @since 1.2
 | 
						|
 * @status updated to 1.2
 | 
						|
 */
 | 
						|
public class ProgressMonitor
 | 
						|
{
 | 
						|
 | 
						|
  /**
 | 
						|
   * The accessible content for this component
 | 
						|
   */
 | 
						|
  protected AccessibleContext accessibleContext;
 | 
						|
 | 
						|
  /**
 | 
						|
   * parentComponent
 | 
						|
   */
 | 
						|
  Component component;
 | 
						|
 | 
						|
  /**
 | 
						|
   * note
 | 
						|
   */
 | 
						|
  String note;
 | 
						|
 | 
						|
  /**
 | 
						|
   * message
 | 
						|
   */
 | 
						|
  Object message;
 | 
						|
 | 
						|
  /**
 | 
						|
   * millisToDecideToPopup
 | 
						|
   */
 | 
						|
  int millisToDecideToPopup = 500;
 | 
						|
 | 
						|
  /**
 | 
						|
   * millisToPopup
 | 
						|
   */
 | 
						|
  int millisToPopup = 2000;
 | 
						|
 | 
						|
  int min, max, progress;
 | 
						|
 | 
						|
  JProgressBar progressBar;
 | 
						|
 | 
						|
  JLabel noteLabel;
 | 
						|
 | 
						|
  JDialog progressDialog;
 | 
						|
 | 
						|
  Timer timer;
 | 
						|
 | 
						|
  boolean canceled;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new <code>ProgressMonitor</code> instance.  This is used to
 | 
						|
   * monitor a task and pops up a dialog if the task is taking a long time to
 | 
						|
   * run.
 | 
						|
   *
 | 
						|
   * @param component The parent component of the progress dialog or
 | 
						|
   *                  <code>null</code>.
 | 
						|
   * @param message A constant message object which works in the way it does
 | 
						|
   *                in {@link JOptionPane}.
 | 
						|
   * @param note A string message which can be changed while the operation goes
 | 
						|
   *             on.
 | 
						|
   * @param minimum The minimum value for the operation (start value).
 | 
						|
   * @param maximum The maximum value for the operation (end value).
 | 
						|
   */
 | 
						|
  public ProgressMonitor(Component component, Object message,
 | 
						|
                         String note, int minimum, int maximum)
 | 
						|
  {
 | 
						|
 | 
						|
    // Set data.
 | 
						|
    this.component = component;
 | 
						|
    this.message = message;
 | 
						|
    this.note = note;
 | 
						|
 | 
						|
    min = minimum;
 | 
						|
    max = maximum;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Hides the dialog and stops any measurements.</p>
 | 
						|
   *
 | 
						|
   * <p>Has no effect when <code>setProgress</code> is not at least
 | 
						|
   * called once.</p>
 | 
						|
   */
 | 
						|
  public void close()
 | 
						|
  {
 | 
						|
    if (progressDialog != null)
 | 
						|
      {
 | 
						|
        progressDialog.setVisible(false);
 | 
						|
      }
 | 
						|
 | 
						|
    if (timer != null)
 | 
						|
      {
 | 
						|
        timer.stop();
 | 
						|
        timer = null;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Updates the progress value.</p>
 | 
						|
   *
 | 
						|
   * <p>When called for the first time this initializes a timer
 | 
						|
   * which decides after <code>millisToDecideToPopup</code> time
 | 
						|
   * whether to show a progress dialog or not.</p>
 | 
						|
   *
 | 
						|
   * <p>If the progress value equals or exceeds the maximum
 | 
						|
   * value the progress dialog is closed automatically.</p>
 | 
						|
   *
 | 
						|
   * @param progress New progress value.
 | 
						|
   */
 | 
						|
  public void setProgress(int progress)
 | 
						|
  {
 | 
						|
    this.progress = progress;
 | 
						|
 | 
						|
    // Initializes and starts a timer with a task
 | 
						|
    // which measures the duration and displays
 | 
						|
    // a progress dialog if neccessary.
 | 
						|
    if (timer == null && progressDialog == null)
 | 
						|
      {
 | 
						|
        timer = new Timer(25, null);
 | 
						|
        timer.addActionListener(new TimerListener());
 | 
						|
        timer.start();
 | 
						|
      }
 | 
						|
 | 
						|
    // Cancels timer and hides progress dialog if the
 | 
						|
    // maximum value is reached.
 | 
						|
    if (progressBar != null && this.progress >= progressBar.getMaximum())
 | 
						|
      {
 | 
						|
        // The reason for using progressBar.getMaximum() instead of max is that
 | 
						|
        // we want to prevent that changes to the value have any effect after the
 | 
						|
        // progress dialog is visible (This is how the JDK behaves.).
 | 
						|
        close();
 | 
						|
      }
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the minimum or start value of the operation.
 | 
						|
   *
 | 
						|
   * @return Minimum or start value of the operation.
 | 
						|
   */
 | 
						|
  public int getMinimum()
 | 
						|
  {
 | 
						|
    return min;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Use this method to set the minimum or start value of
 | 
						|
   * your operation.</p>
 | 
						|
   *
 | 
						|
   * <p>For typical application like copy operation this will be
 | 
						|
   * zero.</p>
 | 
						|
   *
 | 
						|
   * <p>Keep in mind that changing this value after the progress
 | 
						|
   * dialog is made visible has no effect upon the progress bar.</p>
 | 
						|
   *
 | 
						|
   * @param minimum The new minimum value.
 | 
						|
   */
 | 
						|
  public void setMinimum(int minimum)
 | 
						|
  {
 | 
						|
    min = minimum;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Return the maximum or end value of your operation.
 | 
						|
   *
 | 
						|
   * @return Maximum or end value.
 | 
						|
   */
 | 
						|
  public int getMaximum()
 | 
						|
  {
 | 
						|
    return max;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Sets the maximum or end value of the operation to the
 | 
						|
   * given integer.</p>
 | 
						|
   *
 | 
						|
   * @param maximum
 | 
						|
   */
 | 
						|
  public void setMaximum(int maximum)
 | 
						|
  {
 | 
						|
    max = maximum;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns whether the user canceled the operation.
 | 
						|
   *
 | 
						|
   * @return Whether the operation was canceled.
 | 
						|
   */
 | 
						|
  public boolean isCanceled()
 | 
						|
  {
 | 
						|
    // The value is predefined to false
 | 
						|
    // and changes only when the user clicks
 | 
						|
    // the cancel button in the progress dialog.
 | 
						|
    return canceled;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the amount of milliseconds to wait
 | 
						|
   * until the ProgressMonitor should decide whether
 | 
						|
   * a progress dialog is to be shown or not.
 | 
						|
   *
 | 
						|
   * @return The duration in milliseconds.
 | 
						|
   */
 | 
						|
  public int getMillisToDecideToPopup()
 | 
						|
  {
 | 
						|
    return millisToDecideToPopup;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the amount of milliseconds to wait until the
 | 
						|
   * ProgressMonitor should decide whether a progress dialog
 | 
						|
   * is to be shown or not.
 | 
						|
   *
 | 
						|
   * <p>This method has no effect when the progress dialog
 | 
						|
   * is already visible.</p>
 | 
						|
   *
 | 
						|
   * @param time The duration in milliseconds.
 | 
						|
   */
 | 
						|
  public void setMillisToDecideToPopup(int time)
 | 
						|
  {
 | 
						|
    millisToDecideToPopup = time;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the number of milliseconds to wait before displaying the progress
 | 
						|
   * dialog.  The default value is 2000.
 | 
						|
   *
 | 
						|
   * @return The number of milliseconds.
 | 
						|
   *
 | 
						|
   * @see #setMillisToPopup(int)
 | 
						|
   */
 | 
						|
  public int getMillisToPopup()
 | 
						|
  {
 | 
						|
    return millisToPopup;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the number of milliseconds to wait before displaying the progress
 | 
						|
   * dialog.
 | 
						|
   *
 | 
						|
   * @param time  the number of milliseconds.
 | 
						|
   *
 | 
						|
   * @see #getMillisToPopup()
 | 
						|
   */
 | 
						|
  public void setMillisToPopup(int time)
 | 
						|
  {
 | 
						|
    millisToPopup = time;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a message which is shown in the progress dialog.
 | 
						|
   *
 | 
						|
   * @return The changeable message visible in the progress dialog.
 | 
						|
   */
 | 
						|
  public String getNote()
 | 
						|
  {
 | 
						|
    return note;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Set the message shown in the progess dialog.</p>
 | 
						|
   *
 | 
						|
   * <p>Changing the note while the progress dialog is visible
 | 
						|
   * is possible.</p>
 | 
						|
   *
 | 
						|
   * @param note A message shown in the progress dialog.
 | 
						|
   */
 | 
						|
  public void setNote(String note)
 | 
						|
  {
 | 
						|
    if (noteLabel != null)
 | 
						|
      {
 | 
						|
        noteLabel.setText(note);
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        this.note = note;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Internal method that creates the progress dialog.
 | 
						|
   */
 | 
						|
  void createDialog()
 | 
						|
  {
 | 
						|
    // If there is no note we suppress the generation of the
 | 
						|
    // label.
 | 
						|
    Object[] tmp = (note == null) ?
 | 
						|
      new Object[]
 | 
						|
        {
 | 
						|
          message,
 | 
						|
          progressBar = new JProgressBar(min, max)
 | 
						|
        }
 | 
						|
      :
 | 
						|
      new Object[]
 | 
						|
        {
 | 
						|
          message,
 | 
						|
          noteLabel = new JLabel(note),
 | 
						|
          progressBar = new JProgressBar(min, max)
 | 
						|
        };
 | 
						|
 | 
						|
    JOptionPane pane = new JOptionPane(tmp, JOptionPane.INFORMATION_MESSAGE);
 | 
						|
 | 
						|
    // FIXME: Internationalize the button
 | 
						|
    JButton cancelButton = new JButton("Cancel");
 | 
						|
    cancelButton.addActionListener(new ActionListener()
 | 
						|
    {
 | 
						|
      public void actionPerformed(ActionEvent ae)
 | 
						|
      {
 | 
						|
        canceled = true;
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
    pane.setOptions(new Object[] { cancelButton });
 | 
						|
 | 
						|
    // FIXME: Internationalize the title
 | 
						|
    progressDialog = pane.createDialog(component, "Progress ...");
 | 
						|
    progressDialog.setModal(false);
 | 
						|
    progressDialog.setResizable(true);
 | 
						|
 | 
						|
    progressDialog.pack();
 | 
						|
    progressDialog.setVisible(true);
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  /** An ActionListener implementation which does the measurements
 | 
						|
   * and estimations of the ProgressMonitor.
 | 
						|
   */
 | 
						|
  class TimerListener implements ActionListener
 | 
						|
  {
 | 
						|
    long timestamp;
 | 
						|
 | 
						|
    int lastProgress;
 | 
						|
 | 
						|
    boolean first = true;
 | 
						|
 | 
						|
    TimerListener()
 | 
						|
    {
 | 
						|
       timestamp = System.currentTimeMillis();
 | 
						|
    }
 | 
						|
 | 
						|
    public void actionPerformed(ActionEvent ae)
 | 
						|
    {
 | 
						|
       long now = System.currentTimeMillis();
 | 
						|
 | 
						|
       if (first)
 | 
						|
       {
 | 
						|
         if ((now - timestamp) > millisToDecideToPopup)
 | 
						|
         {
 | 
						|
           first = false;
 | 
						|
 | 
						|
 | 
						|
           long expected = (progress - min == 0) ?
 | 
						|
             (now - timestamp) * (max - min) :
 | 
						|
             (now - timestamp) * (max - min) / (progress - min);
 | 
						|
 | 
						|
           if (expected > millisToPopup)
 | 
						|
           {
 | 
						|
             createDialog();
 | 
						|
           }
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
           // We have not waited long enough to make a decision,
 | 
						|
           // so return and try again when the timer is invoked.
 | 
						|
           return;
 | 
						|
         }
 | 
						|
       }
 | 
						|
       else if (progressDialog != null)
 | 
						|
       {
 | 
						|
         // The progress dialog is being displayed. We now calculate
 | 
						|
         // whether setting the progress bar to the current progress
 | 
						|
         // value would result in a visual difference.
 | 
						|
         int delta = progress - progressBar.getValue();
 | 
						|
 | 
						|
         if ((delta * progressBar.getWidth() / (max - min)) > 0)
 | 
						|
         {
 | 
						|
           // At least one pixel would change.
 | 
						|
           progressBar.setValue(progress);
 | 
						|
         }
 | 
						|
       }
 | 
						|
       else
 | 
						|
       {
 | 
						|
         // No dialog necessary
 | 
						|
         timer.stop();
 | 
						|
         timer = null;
 | 
						|
       }
 | 
						|
 | 
						|
      timestamp = now;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the accessible context.
 | 
						|
   *
 | 
						|
   * @return the accessible context.
 | 
						|
   */
 | 
						|
  public AccessibleContext getAccessibleContext()
 | 
						|
  {
 | 
						|
    return accessibleContext;
 | 
						|
  }
 | 
						|
}
 |