Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ProgressMonitor isn't much of a monitor




it seems to me that Sun's ProgressMonitor is a somewhat weak implementation of a decent idea. why is it so hard to get a PM to do -- well, to do almost anything at all?


The ProgressMonitor works just fine, if you implement it properly. Sun has a tutorial on their web site on how to use the ProgressMonitor, and most Swing books have an explanation. The correct set up wasn't obvious to me after reading the books or the tutorial.

The trick is that Swing Component updates are not thread safe. To make them thread safe, all Component updates are sent to the event queue to be handled in turn. This means that if you have an action listener that invokes a method such as doTheCalculation(), this method is invoked after it works its way to the head of the event queue, and NO OTHER EVENTS can be processed until after the doTheCalculation() method returns. All of the updates to the ProgressMonitor are trapped in the event queue, and cannot be processed. When the doTheCalculation() method returns, the ProgressMonitor flashes on the screen, and disappears because the task it is monitoring (doTheCalculation()) has completed. You must set up doTheCalculation() so that it starts a thread and then returns immediately. That way the event queue is not blocked, and the ProgressMonitor will work as it should.


i have a spot in my app where i want a PM to monitor a thread. the PM does in fact pop up, but not until AFTER the most time-consuming part of the algorithm. so the algorithm churns away, then right at the end before the thread exits, the PM pops up and stays open for a moment while the end of the algorithm runs.

It sounds like you understand the thread issue, so I can't tell what you did wrong. To get my application to work, I copied the SwingWorker class from the tutorial, and modified it for my classes. SwingWorker is not part of the API. Here is some of my code. Maybe it will help.


/** Uses a SwingWorker to perform a time-consuming task, while
* monitoring the progress of the task.
* It takes awhile to convert the lines in the archive file
* to a human readable form. This was adapted from the class
* LongTask on the Sun web site in the Swing tutorial on
* progress monitors. The variable "current" was changed to
* "count" which is a class attribute. The tracking is done on
* the basis of how many lines are in the archive and need to be
* processed. To get the progress monitor to work, you need a
* thread with a timer (updateProgressTimer) to fire ActionEvents
* to check on the progress of the task. The ActionListener
* (ConvertDateTimerListener) updates the bar in the
* ProgressMontor showing on the screen. The work, or the task, itself
* which is in its own class (ActualConvertDateTask). The task
* manager which launches a separate thread to perform the task
* (ConvertDateTask), and a SwingWorker, which controls the
* thread itself. This is rather involved. Examples are in
* the Sun tutorial. */
public class ConvertDateTask
{
ConvertDateTask(int lineCount)
{
//Compute length of task...
//figure out
//the number of bytes to read or whatever.
lengthOfTask = lineCount;
}


/** The number of lines in the archive */
private int lengthOfTask;
private String statMessage;


	    /**
	     * Called to start the archive conversion.
	     */
	    void go()
	    {
	        count = 0;
	        final SwingWorker worker = new SwingWorker()
	        {
	            public Object construct()
	            {
	                return new ActualConvertDateTask();
	            }
	        };
	        worker.start();
	    }
			/**	The done() method will now return true. */
	    void stop()
	    {
	        count = lengthOfTask;
	    }
	    /**
	     * Called from the listener to find out if the task has completed.
	     */
	    boolean done()
	    {
	        if (count >= lengthOfTask)
	            return true;
	        else
	            return false;
	    }
	}


what i want is a PM that will pop up right away and will stay open
until the end. for some reason, these two calls do not work to that
end:

                     pm.setMillisToDecideToPopup( 1 );
                     pm.setMillisToPopup( 2 );

furthermore, setting the progress a couple times before entering the
initial, slow part of the routine doesn't work either:

                     pm.setProgress( 1 );
                     pm.setProgress( 10 );
                     pm.setNote( "Getting all items" );

i must be missing something obvious here, right? how do i get a PM to
open immediately or almost immediately?

nicholas

ps all these problems are after i worked around the serious bug in
Apple's ProgressBarUI implementation which results in a terrible memory
leak, by telling swing not to use Apple's UI plaf class.


I haven't used a ProgressMonitor in a couple of years. Could you describe this problem in more detail and your work around, and any issues with the work around?




--
____________________
John St. Ledger        |  "Every calculation based on experience elsewhere,
email@hidden      |              fails in New Mexico."
(505) 667-1154         |
FAX: (505) 665-5283    |      Lew Wallace, Territorial Gov., 1878-81
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden

This email sent to email@hidden


Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.