[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cp-patches] FYI: Implemented ProgressMonitor and ProgressMonitorInputSt
From: |
Robert Schuster |
Subject: |
[cp-patches] FYI: Implemented ProgressMonitor and ProgressMonitorInputStream |
Date: |
Fri, 16 Sep 2005 21:11:11 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.7.11) Gecko/20050916 |
Hi,
this makes the former stub classes useable.
2005-09-16 Robert Schuster <address@hidden>
* javax/swing/ProgressMonitor: Implemented the former stubbed
class and added documentation.
(close): Implemented and added documentation.
(setProgress): Dito.
(isCanceled): Dito.
(setMinimum): Added documentation.
(getMinimum): Dito.
(setMaximum): Dito.
(getMaximum): Dito.
(setNote): Dito.
(getMillisToDecideToPopup): Dito.
(setMillisToDecideToPopup): Dito.
(getMillisToPopup): Dito.
(setMillisToPopup): Dito.
(getNote): Dito.
* javax/swing/ProgressMonitorInputStream: Implemented stub
methods.
(close): Implemented.
(read): Dito.
(reset): Dito.
(skip): Dito.
(getProgressMonitor): Dito.
cu
Robert
Index: javax/swing/ProgressMonitorInputStream.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/javax/swing/ProgressMonitorInputStream.java,v
retrieving revision 1.5
diff -u -r1.5 ProgressMonitorInputStream.java
--- javax/swing/ProgressMonitorInputStream.java 13 Sep 2005 09:17:21 -0000
1.5
+++ javax/swing/ProgressMonitorInputStream.java 16 Sep 2005 19:01:21 -0000
@@ -1,5 +1,5 @@
/* ProgressMonitorInputStream.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.
@@ -39,14 +39,18 @@
package javax.swing;
import java.awt.Component;
+
import java.io.FilterInputStream;
-import java.io.IOException;
import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.IOException;
/**
* ProgressMonitorInputStream
* @author Andrew Selkirk
- * @version 1.0
+ * @author Robert Schuster (address@hidden)
+ * @status updated to 1.2
+ * @since 1.2
*/
public class ProgressMonitorInputStream extends FilterInputStream
{
@@ -57,14 +61,9 @@
private ProgressMonitor monitor;
/**
- * nread
- */
- private int nread;
-
- /**
- * size
+ * read
*/
- private int size;
+ private int read;
/**
* Constructor ProgressMonitorInputStream
@@ -76,16 +75,34 @@
InputStream stream)
{
super(stream);
- // TODO
+
+ int max = 0;
+
+ try
+ {
+ max = stream.available();
+ }
+ catch ( IOException ioe )
+ {
+ // Behave like the JDK here.
+ }
+
+ monitor = new ProgressMonitor(
+ component, message, null, 0, max );
}
/**
* reset
* @exception IOException TODO
*/
- public synchronized void reset() throws IOException
+ public void reset() throws IOException
{
- // TODO
+ super.reset();
+
+ checkMonitorCanceled();
+
+ // TODO: The docs says the monitor should be resetted. But to which
+ // value? (mark is not overridden)
}
/**
@@ -95,7 +112,13 @@
*/
public int read() throws IOException
{
- return 0; // TODO
+ int t = super.read();
+
+ monitor.setProgress(++read);
+
+ checkMonitorCanceled();
+
+ return t;
}
/**
@@ -106,7 +129,21 @@
*/
public int read(byte[] data) throws IOException
{
- return 0; // TODO
+ int t = super.read(data);
+
+ if ( t > 0 )
+ {
+ read += t;
+ monitor.setProgress(read);
+
+ checkMonitorCanceled();
+ }
+ else
+ {
+ monitor.close();
+ }
+
+ return t;
}
/**
@@ -119,7 +156,21 @@
*/
public int read(byte[] data, int offset, int length) throws IOException
{
- return 0; // TODO
+ int t = super.read(data, offset, length);
+
+ if ( t > 0 )
+ {
+ read += t;
+ monitor.setProgress(read);
+
+ checkMonitorCanceled();
+ }
+ else
+ {
+ monitor.close();
+ }
+
+ return t;
}
/**
@@ -130,7 +181,18 @@
*/
public long skip(long length) throws IOException
{
- return 0; // TODO
+ long t = super.skip(length);
+
+ // 'read' may overflow here in rare situations.
+ assert ( (long) read + t <= (long) Integer.MAX_VALUE );
+
+ read += (int) t;
+
+ monitor.setProgress(read);
+
+ checkMonitorCanceled();
+
+ return t;
}
/**
@@ -139,7 +201,8 @@
*/
public void close() throws IOException
{
- // TODO
+ super.close();
+ monitor.close();
}
/**
@@ -148,7 +211,15 @@
*/
public ProgressMonitor getProgressMonitor()
{
- return null; // TODO
+ return monitor;
+ }
+
+ private void checkMonitorCanceled() throws InterruptedIOException
+ {
+ if ( monitor.isCanceled() )
+ {
+ throw new InterruptedIOException("ProgressMonitor was canceled");
+ }
}
}
Index: javax/swing/ProgressMonitor.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/ProgressMonitor.java,v
retrieving revision 1.4
diff -u -r1.4 ProgressMonitor.java
--- javax/swing/ProgressMonitor.java 13 Sep 2005 09:17:21 -0000 1.4
+++ javax/swing/ProgressMonitor.java 16 Sep 2005 19:01:21 -0000
@@ -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,56 +38,74 @@
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 (address@hidden)
+ * @since 1.2
+ * @status updated to 1.2
*/
public class ProgressMonitor
{
/**
* parentComponent
*/
- private Component component;
+ Component component;
/**
* note
*/
- private String note;
+ String note;
/**
* message
*/
- private Object message;
+ Object message;
/**
* millisToDecideToPopup
*/
- private int millisToDecideToPopup;
+ int millisToDecideToPopup = 500;
/**
* millisToPopup
*/
- private int millisToPopup;
+ int millisToPopup = 2000;
- /**
- * min
- */
- private int minimum;
+ int min, max, progress;
- /**
- * max
- */
- private int maximum;
+ JProgressBar progressBar;
+
+ JLabel noteLabel;
+
+ JDialog progressDialog;
+
+ Timer timer;
+
+ boolean canceled;
/**
* Constructor ProgressMonitor
- * @param component TODO
- * @param message TODO
- * @param note TODO
- * @param minimum TODO
- * @param maximum TODO
+ * @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)
@@ -97,93 +115,154 @@
this.component = component;
this.message = message;
this.note = note;
- this.minimum = minimum;
- this.maximum = maximum;
- // TODO
+ min = minimum;
+ max = maximum;
}
/**
- * close
+ * <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()
{
- // TODO
+ if ( progressDialog != null )
+ {
+ progressDialog.setVisible(false);
+ }
+
+ if ( timer != null )
+ {
+ timer.stop();
+ timer = null;
+ }
}
/**
- * setProgress
- * @param progress TODO
+ * <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)
{
- // TODO
+ 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();
+ }
+
}
- /**
- * getMinimum
- * @returns int
+ /** Returns the minimum or start value of the operation.
+ *
+ * @returns Minimum or start value of the operation.
*/
public int getMinimum()
{
- return minimum; // TODO
+ return min;
}
/**
- * setMinimum
- * @param minimum TODO
+ * <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)
{
- this.minimum = minimum;
- // TODO
+ min = minimum;
}
/**
- * getMaximum
- * @returns int
+ * Return the maximum or end value of your operation.
+ *
+ * @returns Maximum or end value.
*/
public int getMaximum()
{
- return maximum; // TODO
+ return max;
}
/**
- * setMaximum
- * @param maximum TODO
+ * <p>Sets the maximum or end value of the operation to the
+ * given integer.</p>
+ *
+ * @param maximum
*/
public void setMaximum(int maximum)
{
- this.maximum = maximum;
- // TODO
+ max = maximum;
}
/**
- * isCanceled
- * @returns boolean
+ * Returns whether the user canceled the operation.
+ *
+ * @returns Whether the operation was canceled.
*/
public boolean isCanceled()
{
- return false; // TODO
+ // The value is predefined to false
+ // and changes only when the user clicks
+ // the cancel button in the progress dialog.
+ return canceled;
}
/**
- * getMillisToDecideToPopup
- * @returns int
+ * 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; // TODO
+ return millisToDecideToPopup;
}
/**
- * setMillisToDecideToPopup
- * @param time TODO
+ * 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;
- // TODO
}
/**
@@ -192,7 +271,7 @@
*/
public int getMillisToPopup()
{
- return millisToPopup; // TODO
+ return millisToPopup;
}
/**
@@ -202,26 +281,143 @@
public void setMillisToPopup(int time)
{
millisToPopup = time;
- // TODO
}
/**
- * getNote
- * @returns String
+ * Returns a message which is shown in the progress dialog.
+ *
+ * @returns The changeable message visible in the progress dialog.
*/
public String getNote()
{
- return note; // TODO
+ return note;
}
/**
- * setNote
- * @param note TODO
+ * <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)
{
- this.note = note;
- // TODO
+ 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;
+ }
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cp-patches] FYI: Implemented ProgressMonitor and ProgressMonitorInputStream,
Robert Schuster <=