aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/ProgressMonitor.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/ProgressMonitor.java')
-rw-r--r--libjava/classpath/javax/swing/ProgressMonitor.java567
1 files changed, 381 insertions, 186 deletions
diff --git a/libjava/classpath/javax/swing/ProgressMonitor.java b/libjava/classpath/javax/swing/ProgressMonitor.java
index 844258f1b90..60f1c7145c0 100644
--- a/libjava/classpath/javax/swing/ProgressMonitor.java
+++ b/libjava/classpath/javax/swing/ProgressMonitor.java
@@ -1,5 +1,5 @@
/* ProgressMonitor.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,191 +38,386 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
/**
- * ProgressMonitor
- * @author Andrew Selkirk
- * @version 1.0
+ * <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 {
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * parentComponent
- */
- private Component component;
-
- /**
- * note
- */
- private String note;
-
- /**
- * message
- */
- private Object message;
-
- /**
- * millisToDecideToPopup
- */
- private int millisToDecideToPopup;
-
- /**
- * millisToPopup
- */
- private int millisToPopup;
-
- /**
- * min
- */
- private int minimum;
-
- /**
- * max
- */
- private int maximum;
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor ProgressMonitor
- * @param component TODO
- * @param message TODO
- * @param note TODO
- * @param minimum TODO
- * @param maximum TODO
- */
- public ProgressMonitor(Component component, Object message,
- String note, int minimum, int maximum) {
-
- // Set Data
- this.component = component;
- this.message = message;
- this.note = note;
- this.minimum = minimum;
- this.maximum = maximum;
-
- // TODO
- } // ProgressMonitor()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * close
- */
- public void close() {
- // TODO
- } // close()
-
- /**
- * setProgress
- * @param progress TODO
- */
- public void setProgress(int progress) {
- // TODO
- } // setProgress()
-
- /**
- * getMinimum
- * @returns int
- */
- public int getMinimum() {
- return minimum; // TODO
- } // getMinimum()
-
- /**
- * setMinimum
- * @param minimum TODO
- */
- public void setMinimum(int minimum) {
- this.minimum = minimum;
- // TODO
- } // setMinimum()
-
- /**
- * getMaximum
- * @returns int
- */
- public int getMaximum() {
- return maximum; // TODO
- } // getMaximum()
-
- /**
- * setMaximum
- * @param maximum TODO
- */
- public void setMaximum(int maximum) {
- this.maximum = maximum;
- // TODO
- } // setMaximum()
-
- /**
- * isCanceled
- * @returns boolean
- */
- public boolean isCanceled() {
- return false; // TODO
- } // isCanceled()
-
- /**
- * getMillisToDecideToPopup
- * @returns int
- */
- public int getMillisToDecideToPopup() {
- return millisToDecideToPopup; // TODO
- } // getMillisToDecideToPopup()
-
- /**
- * setMillisToDecideToPopup
- * @param time TODO
- */
- public void setMillisToDecideToPopup(int time) {
- millisToDecideToPopup = time;
- // TODO
- } // setMillisToDecideToPopup()
-
- /**
- * getMillisToPopup
- * @returns int
- */
- public int getMillisToPopup() {
- return millisToPopup; // TODO
- } // getMillisToPopup()
-
- /**
- * setMillisToPopup
- * @param time TODO
- */
- public void setMillisToPopup(int time) {
- millisToPopup = time;
- // TODO
- } // setMillisToPopup()
-
- /**
- * getNote
- * @returns String
- */
- public String getNote() {
- return note; // TODO
- } // getNote()
-
- /**
- * setNote
- * @param note TODO
- */
- public void setNote(String note) {
- this.note = note;
- // TODO
- } // setNote()
-
-
-} // ProgressMonitor
+public class ProgressMonitor
+{
+ /**
+ * 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;
+
+ /**
+ * Constructor ProgressMonitor
+ * @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 <code>JOptionPane</code>.
+ * @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.
+ *
+ * @returns 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.
+ *
+ * @returns 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.
+ *
+ * @returns 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.
+ *
+ * @returns 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;
+ }
+
+ /**
+ * getMillisToPopup
+ * @returns int
+ */
+ public int getMillisToPopup()
+ {
+ return millisToPopup;
+ }
+
+ /**
+ * setMillisToPopup
+ * @param time TODO
+ */
+ public void setMillisToPopup(int time)
+ {
+ millisToPopup = time;
+ }
+
+ /**
+ * Returns a message which is shown in the progress dialog.
+ *
+ * @returns 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 = ( 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;
+ }
+ }
+
+}