http://www.velocityreviews.com/forums/t135432-danger-jlabel-settext-in-another-thread.html
————————————————————————————————————————————————————————————————
| | |
Guest Posts: n/a |
What about : SwingUtilities.invokeLater( new Runnable() { public void run() { myLabel.setText("hello"); } } } ? (Yamin) wrote: >Hey all, > >I was wondering how dangerous calling JLabel.setText from a thread >other than the event dispatching thread. I know its illegal, but its >in there. I'm looking at some code which does this, but so far it has >not caused any problems and its passed testing. > >Basically, it's just a thread that updates the elapsed time. Don't >ask me why its in its own thread...I didn't write it. > > >Yamin | | |
| |||
| |||
Guest Posts: n/a |
"Yamin" <> wrote in message news: om... > Hey all, > > I was wondering how dangerous calling JLabel.setText from a thread > other than the event dispatching thread. I know its illegal, but its > in there. I'm looking at some code which does this, but so far it has > not caused any problems and its passed testing. > > Basically, it's just a thread that updates the elapsed time. Don't > ask me why its in its own thread...I didn't write it. It's illegal because it will eventually conflict with whatever Swing is doing. Although setting text seems simple, Swing is accessing font sizes, graphics contexts and so forth. Having the underlying string (reference) change may cause any number of problems. In my experience with this particular case (which was a while ago), I usually end up with the label truncated, not resizing and possibly with unexplained crashes. Because the symptoms depend strongly on the timing within the virtual machine, and other platform-dependent things, you may not see any problems until your customer runs the program on a different machine. Cheers, Matt Humphrey http://www.iviz.com/ | | |
| |||
| |||
Guest Posts: n/a |
On 21 Jul 2004 08:13:34 -0700, (Yamin) wrote or quoted : >I was wondering how dangerous calling JLabel.setText from a thread >other than the event dispatching thread. I know its illegal, but its >in there. I'm looking at some code which does this, but so far it has >not caused any problems and its passed testing. Unlike the AWT, Swing is not threadsafe. You can't directly meddle with Swing components, or their backing data models from a second thread. The contract is, if you want to do anything to a Swing component that could have any effect on it's display from an application thread (not the EventDispatchThread itself), you should add it to the event dispatch thread's queue via SwingUtilities.invokeLater( Runnable ) or SwingUtilities.invokeAndWait( Runnable ) so that it will be done on the same thread that Swing itself uses. The good news is, even though you are using Runnable, you don't have the overhead of actually creating a new Thread since you are just calling the run method on the already existing Swing thread. There are a few exceptions to this general rule, most notably it is safe to call repaint and revalidate, JTextComponent.setText and JTextArea.append from any thread. See http://mindprod.com/jgloss/threadsafe.html -- Canadian Mind Products, Roedy Green. Coaching, problem solving, economical contract programming. See http://mindprod.com/jgloss/jgloss.html for The Java Glossary. | | |
| |||
| |||
Guest Posts: n/a |
> It's illegal because it will eventually conflict with whatever Swing is > doing. I second that: it's just a matter of time. -- Sean. | | |
| |||
| |||
Guest Posts: n/a |
Roedy Green <look-> wrote in message news:<>. .. > On 21 Jul 2004 08:13:34 -0700, (Yamin) wrote or > quoted : > > >I was wondering how dangerous calling JLabel.setText from a thread > >other than the event dispatching thread. I know its illegal, but its > >in there. I'm looking at some code which does this, but so far it has > >not caused any problems and its passed testing. > > > Unlike the AWT, Swing is not threadsafe. You can't directly meddle > with Swing components, or their backing data models from a second > thread. The contract is, if you want to do anything to a Swing > component that could have any effect on it's display from an > application thread (not the EventDispatchThread itself), you should > add it to the event dispatch thread's queue via > SwingUtilities.invokeLater( Runnable ) or > SwingUtilities.invokeAndWait( Runnable ) so that it will be done on > the same thread that Swing itself uses. The good news is, even though > you are using Runnable, you don't have the overhead of actually > creating a new Thread since you are just calling the run method on the > already existing Swing thread. > Let me see if I have this straight. Say you have an app that creates a GUI to display something like the amount of data being processed by a NIC card. To monitor this card, you start a thread, passing to it a reference to the GUI you just created in the main thread (EventDispatchThread, presumably). The monitoring thread needs to continually update the GUI with data as it observes it. Does the above reference mean the monitoring thread can't just update the GUI even though it has a direct reference to it? For example, to change a JTextBox on the GUI to say "100 packets received", do I have to create runnable class, which nonetheless won't be invoked at the start of a thread, which updates the JTextBox, and then make it a parameter to either either invokeLater or invokeAndWait, instead of updating JTextBox directly? Is it possible for Sun have thought up a less intuitive way to do this? Regards, Sam90 | | |
| |||
| |||
Guest Posts: n/a |
On 21 Jul 2004 17:13:00 -0700, (Sam) wrote or quoted : >Does the above reference mean the monitoring thread can't just update >the GUI even though it has a direct reference to it? It has to pass a Runnable that does the gui poking to invokeLater. There are some exception noted where you can safely do it yourself. I can see why changing the text in a box is thread safe. All you are doing is pointing the component to a new string -- an atomic operation. So long as the paint routine makes it own copy of the string, all should work. Yet some other posters have said that these actions are not safe after all, even if the JavaDoc claims they are. It never hurts to use a Runnable. It is not that much overhead. It is not as if you were starting a new thread. The advantage of doing the Runnable is maintenance. If someone comes along later and changes the code a little it will still work. Without the Runnable it could stop working mysteriously, and thread problems are notoriously difficult to reproduce and track down. -- Canadian Mind Products, Roedy Green. Coaching, problem solving, economical contract programming. See http://mindprod.com/jgloss/jgloss.html for The Java Glossary. | | |
| |||
| |||
Guest Posts: n/a |
<prior conv. snipped> > > Let me see if I have this straight. Say you have an app that creates a > GUI to display something like the amount of data being processed by a > NIC card. To monitor this card, you start a thread, passing to it a > reference to the GUI you just created in the main thread > (EventDispatchThread, presumably). The monitoring thread needs to > continually update the GUI with data as it observes it. > > Does the above reference mean the monitoring thread can't just update > the GUI even though it has a direct reference to it? For example, to > change a JTextBox on the GUI to say "100 packets received", do I have > to create runnable class, which nonetheless won't be invoked at the > start of a thread, which updates the JTextBox, and then make it a > parameter to either either invokeLater or invokeAndWait, instead of > updating JTextBox directly? The bigger issue is that the GUI in modern systems accounts for 75%-90% of the code, so it's not just some little thing that gets updated every so often. As a complex system in its own right, trying to synchronize it with application code would be a total nightmare, would likely have bugs and would have performance problems because of the constant lock checking. By requiring it be single threaded (except for a couple of methods) Swing can be much less complex, more robust and have better performance and fewer opportunities for bugs. Keep in mind that it's only code that runs in separate threads that needs to deferred to the Event thread. Many apps do much of their work in the event handler itself where no update is required. > Is it possible for Sun have thought up a less intuitive way to do > this? I have to admit it took a while to understand what was going on, particularly because I was raised in the pre-GUI days where a program had total control of the machine. But now I really like it and having written many multithreaded (collaborative, distirbuted, etc, etc) systems I would make the same design decision. Cheers, Matt Humphrey http://www.iviz.com/ | | |
| |||
| |||
Guest Posts: n/a |
On Wed, 21 Jul 2004 21:36:30 -0400, "Matt Humphrey" <> wrote or quoted : > But now I really like it and having written >many multithreaded (collaborative, distirbuted, etc, etc) systems I would >make the same design decision. Hear Hear! Any time you have race conditions possible, you get into bugs that only show up on Christmas eve, and then disappear so you can't nail them. invokeLater is a small penalty to pay for stability and bug avoidance. Everything happens on the Swing thread in nice orderly little chunks, with no unpredictable interleaving. -- Canadian Mind Products, Roedy Green. Coaching, problem solving, economical contract programming. See http://mindprod.com/jgloss/jgloss.html for The Java Glossary. | | |
| |||
| |||
Guest Posts: n/a |
Thanks for all the responses guys. Yeah, I know about invokelater and what not. That's why I asked the question as I knew of its illegality and how to write it properly. Its not my code, and sometimes its a mission to get someone to change something when its 'not broken'. But I guess the general answer is that its VM specific. Yamin (Yamin) wrote in message news:<. com>... > Hey all, > > I was wondering how dangerous calling JLabel.setText from a thread > other than the event dispatching thread. I know its illegal, but its > in there. I'm looking at some code which does this, but so far it has > not caused any problems and its passed testing. > > Basically, it's just a thread that updates the elapsed time. Don't > ask me why its in its own thread...I didn't write it. > > > Yamin | | |
|