*NEWBIE* UI not updating when java program busy
Hey there, I've been working with Java for a while, switching from Delphi, which I've been working with for years.
The problem I'm having:
I've written a java program where you enter a source folder, a destination folder, and extension filters, and the program will step through the source recursively, picking up any files with the extensions required and move them to sub-folders under the destination folders. You've heard it all before I bet, just a simple program that sorts things I've downloaded (MP3, WMA, AVI etc).
There's a niggling problem with the algorithm somewhere, which I'd like to hunt down. It doesn't seem to happen on my work PC, but other people are having problems with it so I'd like to do some debugging.
To do so, I've added a jTextArea to the form.
Now, when I'm in the traversal of the folder structure, and there is an extension filter match, my idea was to call jTextArea.append(aFile + " MATCH!\n");
The output of which I'd hope to be something like this:
S:\Backup\Celina\Documents and Settings\Celina\My Documents\My Music\Punk Rocker.mp3 MATCH!
(next file match)
(next file match)
etc. You get the idea.
Unfortunately the jTextArea doesn't get updated till after everything has completed, not while it's traversing, as I'd like.
I've tried adding a jTextArea.repaint(); directly after the append, but this makes no difference. In fact, switching applications to something else then back again causes the UI to show only a completely gray box. Until it's finished, that is. Basically nothing on the UI updates while the search algorithm is doing it's thing.
In Delphi, if I ever had this problem I simply called Application.ProcessMessages();
This would slow the general thing down, but at least the GUI would get updated.
How do I fix this in Java?
Oh, this is VERY prominent when traversing network drives, less so with local files.
Regards,
Ramrunner.
[2021 byte] By [
Ramrunnera] at [2007-10-3 8:40:12]

I would guess you are running your main processing in the Event Dispatch Thread - probably in the action of a button press? In a nutshell, every time you are appending to your text area, a new event is queued onto the Event Disptach Thread to process this. Unfortunately, these events wont be executed until your file processing is finished, as it is blocking the queue. The result is no GUI updates for you, and some nasty gui freeze.
Anyways, take the time out to learn about the Event Dispatch Thread. To solve your problem, you are going to have to thread your main file processing so it does not occur in the event dispatch thread, allowing your gui to be painted unhindered with the new contents you have specified.
Its very easy, just understand your problem first!
> I would guess you are running your main processing in
> the Event Dispatch Thread - probably in the action of
> a button press?
Spot on. It is running from a button. Now, the fact that that causes main processing to be run in a thing called the Event Dispatch Thread, THAT I didn't know. Good catch.
> In a nutshell, every time you are
> appending to your text area, a new event is queued
> onto the Event Disptach Thread to process this.
> Unfortunately, these events wont be executed until
> your file processing is finished, as it is blocking
> the queue. The result is no GUI updates for you, and
> some nasty gui freeze.
That's what I'm seeing. Gone are the days of simple linear programming that I'm far more used to (C, Turbo Pascal). At least in Delphi this was relatively easy to get around. I guess I'm forced to learn about these threads. Oh well, I guess I had to learn some time.
>
> Anyways, take the time out to learn about the Event
> Dispatch Thread. To solve your problem, you are going
> to have to thread your main file processing so it
> does not occur in the event dispatch thread, allowing
> your gui to be painted unhindered with the new
> contents you have specified.
>
> Its very easy, just understand your problem first!
Doesn't sound easy at all, but I believe you. I'll do the reading as suggested by the previous poster, and if I really still don't get anything happening I shall return.
Many thanks for at least diagnosing what is going on. Hard to fix something when my brain logic seems to think it shouldn't be happening!!!
Regards,
Ramrunner
No problem - I would think we've all been there - I certainly remember it myself!
Heres a starter for 10
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Thread thread = new Thread(new Runnable()
{
public void run()
{
// file processing code in here
textArea.append("append string that will be seen")
}
});
thread.start();
}
});
Points worth noting.
1) The append method for the text area is thread safe, meaning that it need not necessarily be invoked from the event dispatch thread. Most swing methods are not however, and if you need to invoke them from outwith the event dispatch thread, you should use the SwingUtilities.invokeLater() method.
2) Although this will work, you may now have gui control issues that you need to consider. For example, you may want to disable the button whilst the thread is still executing so that it cannot be started again until finished.
Hope this gets you on your way. You'll hit a 'matrix' moment soon where it all makes sense - promise!
Although this will work, you may now have gui control issues that you need to consider. For example, you may want to disable the button whilst the thread is still executing so that it cannot be started again until finished.
For what it's worth, I find the best way to do this is that I have my own Action implementation which disables itself during execution (it also handles threading behaviour, allowing parts of the action to be executed on and off the EDT). This means any time I need to write an action I don't need to worry about this stuff.
Actions are, where directly accessible by the user, always preferable to plain ActionListeners - but I've posted reasons for that many times on other threads so you can search for that.