?
Solved

Modify Swing Components

Posted on 2006-06-10
24
Medium Priority
?
430 Views
Last Modified: 2013-11-23
Sun makes the statement:

"Once a Swing component has been realized, all code that might affect
or depend on the state of that component should be executed in the
event-dispatching thread."

Following this recommandation may cause a lot of additional code,
especially when dealing with GUI events, that trigger time consuming
tasks. I use to write event-driven programs that works like a state
machine: the listener only changes states and NOTHING ELSE. A special
thread contains a state event loop does all the task. It also updates
Swing components. Is this safe enough? (I never had a problem.)
0
Comment
Question by:pluess
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 8
  • 2
  • +1
24 Comments
 
LVL 24

Accepted Solution

by:
sciuriware earned 128 total points
ID: 16877394
Simple: the 'actionPerformed()' must launch threads for all consuming processes.
Those can modify Swing components, like setEnabled(), setVisible().
Only adding and removing components to JPanel's and other containers must
be followed by a refresh on that container.
That's the way I've done it for years, but stay in control over those threads!

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16877468
Example of SWING modification on the fly:

  JPanel p;
...............

  p.add(someButton);   // Button created because of some event (button?)
  p.revalidate();      // That's all needed.

...............................
  p.remove(someButton); // Not needed anymore.
  p.revalidate();      // Ready.


;JOOP!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16878529
hey you can launch threads to complete tasks but all the threads should be executed through the event dispatching threads since the swing comp are not thread safe. You can do that using invokeLater and invokeAndWait methods in SwingUtility class
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 24

Expert Comment

by:sciuriware
ID: 16879740
>>> but all the threads should be executed through the event dispatching threads

Nonsense, that's the only way: from the ONE event dispatching thread.
When you click a button, where do you end up? in actionPerformed()
and where is that? Yes, in that thread.

;JOOP!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16879930
go thruogh the below link,

http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html

hope now it make sense!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16879935
>>the 'actionPerformed()' must launch threads for all consuming processes.
Those can modify Swing components
>>

   Better you read some article before making such wrong statements!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16879957
Funny, what is wrong with that?
You said: "should be executed through the event dispatching threads".
Is there another place than in 'actionPerformed()'?
You may have read more than me, but did you ever apply this?

;JOOP!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16879986
your code,

public void actionPerformed( ActionEvent ae ){
  Thread thread = new Thread(){
     public void run(){
        //task
     }
  }
} // more possibility for DL

mine,

public void actionPerformed( ActionEvent ae ){
  SwingUtilites.invokeLater( new Runnable(){
     public void run(){
        //task
     }
  } ;
}

Hope u understand the diff now!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16880013
Tell me.
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16880029
gothrough the link!
0
 
LVL 26

Assisted Solution

by:ksivananth
ksivananth earned 124 total points
ID: 16880045
and here are some more,

http://java.sun.com/developer/technicalArticles/Threads/swing/

And a clear explanation,

"In Java programs with GUIs that use Swing and/or the AWT, the AWT event handler runs in its own thread. Developers must be careful to not tie up this GUI thread performing time-consuming work, because it is responsible for handling user events and redrawing the GUI. In other words, the program will appear frozen whenever the GUI thread is busy. Swing callbacks, such as Mouse Listeners and Action Listeners are all notified (by having appropriate methods called) by the Swing thread. This approach means that any substantial amount of work the listeners are to do must be performed by having the listener callback method spawn another thread to do the work. The goal is to get the listener callback to return quickly, allowing the Swing thread to respond to other events.

If a Swing thread is running asynchronously, responding to events and repainting the display, how can other threads modify Swing state safely? As I just mentioned, Swing callbacks run in the Swing thread; therefore, they can safely modify Swing data and draw to the screen.

But what about other changes that don't happen as a result of a Swing callback? Having a non-Swing thread modify Swing data is not thread safe. Swing provides two methods to solve this problem: invokeLater() and invokeAndWait(). To modify the Swing state, simply call either of these methods, passing a Runnable object that does the proper work. Because Runnable objects are usually their own threads, you might think that this object is spawned off as a thread to execute. In fact, this is not the case, as that too would not be thread safe. Instead, Swing puts this object in a queue and executes its run method at an arbitrary point in the future. This makes the changes to Swing state thread safe."
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16880142
You did not understand the thread mechanism.
The magic is in:

  p.revalidate();      // Ready.

I have written professional programs with hundreds of threads that independently painted or modified
the screen.
Of course it could all be my imagination.

pluess, can you react a bit; we are doing this all for YOU!

;JOOP!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16880156
yes u only understand the thread mechanism, me and all who created the articles are don't!

always prevention is better than cure!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16880165
From 1968: Those who can, do; those who can't, teach; those who cannot teach, publish.
Not my words.

;JOOP!
0
 
LVL 92

Assisted Solution

by:objects
objects earned 124 total points
ID: 16883947
> public void actionPerformed( ActionEvent ae ){
> A special
> thread contains a state event loop does all the task. It also updates
> Swing components. Is this safe enough? (I never had a problem.)

Doesn't sound like it. you should use invokeLater() and invokeAndWait() to update the gui

>  SwingUtilites.invokeLater( new Runnable(){
>     public void run(){
>        //task
>     }
>  } ;
> }

If task is lengthy then that code will block the gui.
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16883982
objects you are most experienced here.
May I presume that you agree that launching new threads
(or activating other threads) is the right way?

;JOOP!
0
 
LVL 92

Expert Comment

by:objects
ID: 16883993
If the processing is lengthy and you don't want to freeze your gui then you need to start a new thread.
And if that thread needs to update the gui then it should use invokeLater() and invokeAndWait() to do thos updates.
0
 
LVL 30

Assisted Solution

by:Mayank S
Mayank S earned 124 total points
ID: 16884013
I would recommend a thread-pool thread to run it if the processing is lengthy (Java 5)
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16885984
I never needed that. My program was running 100's of threads for weeks (large banking conversion).
I wonder why I never had to use invokeLater() etc.
It worked as a charm.
(JAVA 5 on W2003).

;JOOP!
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16886016
>> I never needed that.

Thread-pool?
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16887186
>>If the processing is lengthy and you don't want to freeze your gui then you need to start a new thread.
And if that thread needs to update the gui then it should use invokeLater() and invokeAndWait() to do thos updates.
>>

   Exactly, I just posted the code for an example!
0

Featured Post

Introducing Priority Question

Increase expert visibility of your issues by participating in Priority Question, our latest feature for Premium and Team Account holders. Adjust the priority of your question to get emergent issues in front of subject-matter experts for help when you need it most.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
This video teaches viewers about errors in exception handling.
Suggested Courses
Course of the Month15 days, 11 hours left to enroll

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question