• Post Reply Bookmark Topic Watch Topic
  • New Topic

SwingUtilities.invokeLater vs calling run method

 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have an assignment where the Main to launch was provided with the SwingUtilities.invokeLater method used but not explained:

import javax.swing.SwingUtilities;




I read up on it and understand it has something to do with threads, which I have not really learned about yet...so I am not going to ask how the method works yet..still reading up on it, but what I DON'T understand is why when I just call the run method on the following code, when I add JTextField to the frame, all I get is a blank frame. The JButton and JLabel disappear. If I replace the JTextField with say another JButton, it is fine... When I go with the SwingUtilities.invokeLater, the JTextField occupies one quadrant as it is supposed to. So my question is why when I invoke the run method in NoticeBoard, does adding a JTextField make everything blank?

NoticeBoard:




 
A.J. Côté
Ranch Hand
Posts: 417
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I can't answer your question right now but just out of curiosity can you try this:



just for fun to see if it gives the same results as:



Thanks!
 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, that gives same result as if I just called the run method..a blank frame.....
 
A.J. Côté
Ranch Hand
Posts: 417
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So for some reason you might need to go through SwingUtilities to run on the AWT dispatch thread I guess...



https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater%28java.lang.Runnable%29

https://docs.oracle.com/javase/7/docs/api/java/awt/EventQueue.html#invokeLater%28java.lang.Runnable%29
 
Stephan van Hulst
Bartender
Posts: 6583
84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Swing uses a special Event Dispatch Thread that interacts with the OS to catch events and draw components on the screen. Running just the code that sets up your interface will not do anything special to let it react to events and repaint it.

You don't need to know in-depth about multi-threading to be able to write Swing applications, but it's definitely recommended and even required for more complex scenarios.

[edit]

I confused myself, Campbell is right of course. Problems you may experience from running GUI related code in a thread other than that EDT are likely caused because of synchronization problems.
 
Campbell Ritchie
Marshal
Posts: 52580
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Find a copy of Core Java II by Horstmann and Cornell (9th ed, Java7 ed printed 2012, pages 909‑924). That explains the history of the EDT and shows an example where using multiple threads causes an Exception. The problem is that Swing is not thread safe. H&C suggest it is probably not possible to create a thread safe GUI framework. They say that attempts so to do were unsuccessful. The idea is that you always run GUIs from the EDT, and you start the EDT with Swingutilities#invokeLater. The similar method in ThreadQueue does exactly the same thing. There is also invokeAndWait but that is awkward to use because it declares lots of checked Exceptions. You should therefore always use invokeLater to start the EDT. You can use invokeLater elsewhere. If you do so, then your code plugs into the EDT rather than starting a new Thread. If you use new Thread(...), you will be multi‑threading your GUI and there is a risk of concurrency problems, as shown in the example from H&C.

∴ Always use invokeLater (or similar) for anything which might be applied to any Swing components.

The reason you have a blank frame is that you are calling setVisible before you add the other components.
 
A.J. Côté
Ranch Hand
Posts: 417
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Swing uses a special Event Dispatch Thread that interacts with the OS...


Well, I already figured that out.

Thanks Stephan,
 
A.J. Côté
Ranch Hand
Posts: 417
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Swing uses a special Event Dispatch Thread that interacts with the OS to catch events and draw components on the screen. Running just the code that sets up your interface will not do anything special to let it react to events and repaint it.

You don't need to know in-depth about multi-threading to be able to write Swing applications, but it's definitely recommended and even required for more complex scenarios.

[edit]

I confused myself, Campbell is right of course. Problems you may experience from running GUI related code in a thread other than that EDT are likely caused because of synchronization problems.


Nah, still the same, learn your apis and use them appropriately.
 
Campbell Ritchie
Marshal
Posts: 52580
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And the API tells you clearly that Swing is not thread safe.
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
when I add JTextField to the frame, all I get is a blank frame.


The basic structure of your code is wrong. The problem is the components have a size of (0, 0) so there is nothing to paint.

You need to add the components to your frame BEFORE making the frame visible. Then the layout manager can do its job and set the size/location of the components

So your code should be something like:



99% of the time on a simple example like this it doesn't matter if you use the SwingUtilities.invokeLater(...), the code will work.

However, NOT using the SwingUtilities.invokeLater(...) can cause random problems and you don't want to waste time debugging problems that only occur randomly.

So my advice to you is to ALWAYS use the SwingUtilities.invokeLater(...).

I suggest you read the section from the Swing tutorial on Concurrency in Swing for more information. I also suggest you follow the example code in the tutorial for a consistent way to structure your code. Your class should not implement runnable.
 
A.J. Côté
Ranch Hand
Posts: 417
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:And the API tells you clearly that Swing is not thread safe.


Hence, just learn to use the api appropriately.
 
A.J. Côté
Ranch Hand
Posts: 417
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK. Using an API is almost like signing a marriage contract.
 
Campbell Ritchie
Marshal
Posts: 52580
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, as Bertrand Meyer will tell you, the API constitutes a contract. The provider of the API makes a contract that the method/class will work in a particular way … as long as you use it according to their instructions. If an API documentation says that a certain method requires a particular argument, then you must supply that argument. Let us imagine that you have method foo(int) and the documentation says that the int must be positive. IF you pass a negative argument, the following may happen:-
  • An Exception causes the application to crash.
  • The app goes into an infinite loop.
  • The app asks for new input.
  • The app shows an error message.
  • The app chooses a default value which is positive.
  • The app chooses a random value which is positive.
  • A race condition produces incorrect results.
  • Deadlock.
  • A wrong result is displayed or recorded.
  • The method call is ignored.
  • Nothing unusual.
  • Any of the above can happen, or several things. You often cannot predict which. But if you are going to pass an incorrect argument or use an API in an incorrect manner, then the provider of the API will tell you, you only have yourself to blame.
     
    Campbell Ritchie
    Marshal
    Posts: 52580
    119
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Rob Camick wrote:. . . 99% of the time on a simple example like this it doesn't matter if you use the SwingUtilities.invokeLater(...), the code will work. . . .
    That is one of the possibilities I mentioned: nothing unusual. But it is as well to learn the correct method as soon as possible, rather than saying, “Nothing went wrong last time I did it like that.”
     
    Ted Schrey
    Ranch Hand
    Posts: 57
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This is all very helpful information as I am just starting GUI. I appreciate it!
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!