🔒 Locked
[java] threads
Advertisement
Original Post
i'm in the process of learning swing so instead of just writing a GUI that doesn't do anything, i decided to write an application that actually does something.
everything works great apart from that i don't know how to use threads. the thing is that one operation "freezes" the gui. i know this can be solved by using threads for the processor hungry operation, just not how.
i have these classes:
Main // doh
GUI // the gui. extends JFrame
Application // this is where the calculations are done
(more classes, but these aren't important)
Main creates a new Application. Application calls the GUI and when the user performs a certain action, a cpu hungry operation performs some calculations. I'd like to run this in a new thread instead of the main thread so that i won't lock up the GUI.
any ideas how to implement this or where to find more information? i've checked java.sun.com, but i weren't able to adapt their examples to suit my needs.
_______________________________
catch (SpellingException e) {}
Edited by - mill-o on November 9, 2001 7:54:46 AM
Edited by - mill-o on November 9, 2001 8:26:44 AM
When the user click on a button, launch a thread (have a look to the Thread class in the JDK) that will do all the operations without blocking the whole GUI. You may need to disable some widgets until the operation is complete to prevent the user from launching too many threads.
Edited by - Prosper/LOADED on November 9, 2001 9:01:03 AM
Edited by - Prosper/LOADED on November 9, 2001 9:01:03 AM
ok.. now Application extends Thread, meaning that when I create a new Application I create a new thread? the GUI is still not updating. i even tried app.setPriority(app.MIN_PRIORITY), but that didn't help either. all that happened is that the task took ~20000 ms instead of ~8000 ms. you can see the code below:
in Application all the job is done in the run-method, which I suppose is correct.
any ideas, anybody?
______________________________
catch (SpellingException e) {}
Edited by - mill-o on November 9, 2001 2:27:28 PM
|
in Application all the job is done in the run-method, which I suppose is correct.
any ideas, anybody?
______________________________
catch (SpellingException e) {}
Edited by - mill-o on November 9, 2001 2:27:28 PM
Well, you''re doing a couple of things wrong. First off, you are updating a swing component from the event dispatch thread (the thread that calls your event listeners). Always update Swing compoents from other threads. Do this by passing your progressMonitor to the new Application when it''s created, and update the monitor in the run method whenever appropriate.
This also removes the need for the while loop, letting the event dispatch thread go about its business (repainting components & the such) while you do the stuff in app.run().
Of course, if progressMonitor or output (or anything else for that matter) are shared between different threads, be sure to place locks around them so that 2 threads don''t modify each other''s data. Do a search for "synchronized" on Goolge or Sun''s Java site for more info.
"So crucify the ego, before it''s far too late. To leave behind this place so negative and blind and cynical, and you will come to find that we are all one mind. Capable of all that''s imagined and all conceivable."
- Tool
This also removes the need for the while loop, letting the event dispatch thread go about its business (repainting components & the such) while you do the stuff in app.run().
|
Of course, if progressMonitor or output (or anything else for that matter) are shared between different threads, be sure to place locks around them so that 2 threads don''t modify each other''s data. Do a search for "synchronized" on Goolge or Sun''s Java site for more info.
"So crucify the ego, before it''s far too late. To leave behind this place so negative and blind and cynical, and you will come to find that we are all one mind. Capable of all that''s imagined and all conceivable."
- Tool
quote:
First off, you are updating a swing component from the event dispatch thread (the thread that calls your event listeners). Always update Swing compoents from other threads.
This is exactly wrong... It creates MANY race conditions in your code. Anything that updates a GUI component from any thread other than the dispatching thread should use SwingUtilities.invokeLater(Runnable) to execute the updates in the GUI thread.
mkay, i tried that. Application now implements Runnable instead of extending Thread. Application is now called as can be seen below:
The GUI and the ProgressBar don''t update properly now. I guess I didn''t understand you totally..
______________________________
catch (SpellingException e) {}
if (returnVal == JFileChooser.APPROVE_OPTION) {
createProgressMonitor();
output.setText("");
javax.swing.SwingUtilities.invokeLater(new Application(fc.getSelectedFile(), progressMonitor, output));
}
The GUI and the ProgressBar don''t update properly now. I guess I didn''t understand you totally..
______________________________
catch (SpellingException e) {}
Yeah, you misunderstood...
Definately run the logic in a separate thread. However, when you need to update swing components from that thread, use SwingUtilities.invokeLater(Runnable) to update the swing components, and NOTHING else.
Like this:
Unfortunately, that will take a small bit of fiddling to get to work properly, as the value v that the progress bar is being update with will either have to be final (in which case it will have to be declared and initialized right before the call to invokeLater), or it will need to not be a local variable.
Definately run the logic in a separate thread. However, when you need to update swing components from that thread, use SwingUtilities.invokeLater(Runnable) to update the swing components, and NOTHING else.
Like this:
|
Unfortunately, that will take a small bit of fiddling to get to work properly, as the value v that the progress bar is being update with will either have to be final (in which case it will have to be declared and initialized right before the call to invokeLater), or it will need to not be a local variable.
okay.. i did as you suggested and it works, more or less. i wrote a class Progress which can be seen below.
the thing is that now the whole task takes 17000 ms to complete instead of 8000 ms. is this the price i have to pay or i'm doing something wrong?
______________________________
catch (SpellingException e) {}
Edited by - mill-o on November 12, 2001 2:19:21 PM
Edited by - mill-o on November 12, 2001 2:19:37 PM
|
the thing is that now the whole task takes 17000 ms to complete instead of 8000 ms. is this the price i have to pay or i'm doing something wrong?
______________________________
catch (SpellingException e) {}
Edited by - mill-o on November 12, 2001 2:19:21 PM
Edited by - mill-o on November 12, 2001 2:19:37 PM
hehe okay, sounds reasonable. the textfile i''m using to test the program with contains ~200000 lines of text and i''m updating the progress bar in a loop which loops for every line, in other words, 200000 updates 
i''ll fiddle a little and post the new results later tonight
i''ll fiddle a little and post the new results later tonight
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement