InvokeLater does not update in time  
Author Message
Ikke





PostPosted: 2006-10-9 20:22:00 Top

java-programmer, InvokeLater does not update in time Hi everybody,

I'm working on a small application that scans a lot of files for
information.

To let the user know what is going on, I update the following components:
- a JList containing log messages
- a JProgressBar indicating the progress in the current file
- a JProgressBar indicating global progress

The scan progress is a separate thread. I noticed that the JList was not
getting updated correctly, and after some Googling I found out that this
was because I was not updating it in the Event Dispatching Thread. So I
added the following piece of code:

--- code ---
if (SwingUtilities.isEventDispatchThread())
{
sv.showMessage(message);
}
else
{
Runnable run = new Runnable()
{
public void run()
{
sv.showMessage(message);
}
};
SwingUtilities.invokeLater(run);
}
--- /code ---

"sv" is the JFrame containing the JList. This would ensure that a) the
JList would get updated, and b) that the results would be displayed in
the EDT.

So far so good - but as a result of the amount of files, there will be
thousands and thousands of Runnables, each waiting their turn to get
executed.

The end result is a display in which both JProgressBars are both at 100%,
and the JList still is updating a list of what's going on.

How can I let the update process for the JList keep pace with the
JProgressBars?

Thanks in advance,

Ikke
 
opalpa opalpa@gmail.com http://opalpa.info





PostPosted: 2006-10-9 23:09:00 Top

java-programmer >> InvokeLater does not update in time instead of invokeLater you can invokeAndWait

opalpa
email***@***.com
http://opalpa.info/

 
Ian Wilson





PostPosted: 2006-10-10 0:52:00 Top

java-programmer >> InvokeLater does not update in time Ikke wrote:
> Hi everybody,
>
> I'm working on a small application that scans a lot of files for
> information.
>
> To let the user know what is going on, I update the following components:
> - a JList containing log messages
> - a JProgressBar indicating the progress in the current file
> - a JProgressBar indicating global progress
>
> The scan progress is a separate thread. I noticed that the JList was not
> getting updated correctly, and after some Googling I found out that this
> was because I was not updating it in the Event Dispatching Thread. So I
> added the following piece of code:
>
> --- code ---
> if (SwingUtilities.isEventDispatchThread())
> {
> sv.showMessage(message);
> }
> else
> {
> Runnable run = new Runnable()
> {
> public void run()
> {
> sv.showMessage(message);
> }
> };
> SwingUtilities.invokeLater(run);
> }
> --- /code ---
>
> "sv" is the JFrame containing the JList. This would ensure that a) the
> JList would get updated, and b) that the results would be displayed in
> the EDT.
>
> So far so good - but as a result of the amount of files, there will be
> thousands and thousands of Runnables, each waiting their turn to get
> executed.
>
> The end result is a display in which both JProgressBars are both at 100%,
> and the JList still is updating a list of what's going on.
>
> How can I let the update process for the JList keep pace with the
> JProgressBars?

Even if your program can process 1000 files a second, it's not sensible
to expect a human to read 1000 filenames a second, so I'd not show the
human 1000 filenames a second.

I'd surround that block with some code to keep track of the time that
you last invoked showMessage and skip the block unless 500ms has elapsed.

An equivalent might be to put the name of the current file in a suitable
variable (every iteration) and have a scheduled repeating Timer task to
feed the current value from that to showMessage every 500ms.

Some filenames will get skipped from the user feedback but the end user
is not going to notice anyway if they are flashing past too quickly to read.
 
 
opalpa opalpa@gmail.com http://opalpa.info





PostPosted: 2006-10-10 1:55:00 Top

java-programmer >> InvokeLater does not update in time
> - a JList containing log messages

The messages being log strongly suggests that items contained are not
for user selection.

But a JList component allows the user to select one or more objects
from a list.

Perhaps instead of JList a JTextArea that is uneditable?

All the best,
opalpa
email***@***.com
http://opalpa.info/

 
 
Ikke





PostPosted: 2006-10-10 2:19:00 Top

java-programmer >> InvokeLater does not update in time Ian Wilson <email***@***.com> wrote in
news:email***@***.com:

<snipped>
> Even if your program can process 1000 files a second, it's not
> sensible to expect a human to read 1000 filenames a second, so I'd not
> show the human 1000 filenames a second.
>
> I'd surround that block with some code to keep track of the time that
> you last invoked showMessage and skip the block unless 500ms has
> elapsed.
>
> An equivalent might be to put the name of the current file in a
> suitable variable (every iteration) and have a scheduled repeating
> Timer task to feed the current value from that to showMessage every
> 500ms.
>
> Some filenames will get skipped from the user feedback but the end
> user is not going to notice anyway if they are flashing past too
> quickly to read.

Thanks for your reply!

I realised the same, shortly after posting my question. It was a bit
foolish to show all those filenames, because a user would not be interested
in them.

Instead, I now log the folder I'm working on, and I have added the filename
to the progressbar (in the form of filename - percentage). This works much
much better.

Also thanks to opalpa, I'm going to try the InvokeAndWait method on the
remaining log calls.

As for the JTextArea, I have tried that in the past, but it doesn't look as
nice imho. Having a JList which gets updated, and selecting the last line
each time looks better than plain text in a box.

Thanks again,

Ikke