Java Thread Programming 1.9.1-Threads and Swing

Source: Internet
Author: User
Why isn' t the Swing Toolkit Multithread-Safe?  After Swing components have been displayed on the screen, They shoshould only be operated on by the event-handling thread. The event-handling thread (or just event thread) is started automatically by the Java VM when an application has a graphical interface. The event thread callmethods like Paint () On Component , Actionreceivmed () On ActionListener ,And all of the other event-handling methods. When the Swing component is displayed on the screen, it should only be operated by the message processing thread. When the application has a graphical interface, the Java Virtual Machine will automatically create a message processing thread to call the Component paint () method, ActionListener actionreceivmed () method, and other message processing methods. Most of the time, modifications to Swing components are done in the event-handling methods. because the event thread CILS these methods, it is perfectly safe to directly change components in event-handling code. simpleEvent (see Listing 9.1) shows safe Swing code. /** Created on 2005-7-17 ** Java Thread Programming-Paul Hyde * Copyright? 1999 Sams Publishing * Jonathan Q. bo Study Notes **/package org. tju. msnrl. jonathan. thread. chapter9; import java. awt. *; import java. awt. event. *; import javax. swing. *;/*** @ author Jonathan Q. bo from tju msnrl ** E-mail: jonathan.q.bo@gmail.com * Blog: blog.csdn.net/jonathan_q_bo * blog.yesky.net/jonathanundersun ** Enjoy Life with Sun! **/Public class SimpleEvent {private static void print (String msg) {String temp = Thread. currentThread (). getName (); System. out. println (temp + "-" + msg);} public static void main (String [] args) {final JLabel lb = new JLabel ("_____"); JButton bt = new JButton ("Click here! "); JPanel pn = new JPanel (new FlowLayout (); pn. add (lb); pn. add (bt); bt. AddActionListener(New ActionListener() {Public void Actionreceivmed(ActionEvent e) {print ("do action..."); lb. setText ("Clicked! ") ;}}); JFrame fm = new JFrame (" simple event "); fm. setContentPane (pn); fm. setSize (300,100); fm. setVisible (true) ;}} console output result: AWT-EventQueue-0-do action... indicates that the message thread is processing Using SwingUtilities. invokeAndWait ()  The developers of the Swing toolkit realized that there wocould be times when an external thread wowould need to make changes to Swing components. they created a mechanic that puts a reference to a chunk of code on the event queue. when the event thread gets to this code block, it executes the code. this way, the GUI can be changed inside this block of code by the event thread. sometimes external threads (non-Message Processing threads) need to operate Sw Ing component. Some code can be put on the message queue and executed by the message thread, so that the GUI can be changed by the code block of the External Thread (still by calling the message thread ). The SwingUtilities class has a static invokeAndWait () method available to use to put references to blocks of code onto the event queue: public static void InvokeAndWait(Runnable target) throws interruptedexception, invocationtargetexception an interruptedexception is thrown if the thread that called invokeandwait () is interrupted before the block of Code referred to by target completes. an invocationtargetexception (a class in the Java. lang. reflect package) is thrown if an uncaught exception is thrown by the code inside run (). if the invokeandwait () thread in is called before the target is completed Terrupted, interruptedexception is thrown. If an uncaptured exception exists in the run () method, the invocationtargetexception () exception (which belongs to Java. lang. reflect package) A new thread is not created when runnable is used with swingutilities. invokeandwait (). the event thread will end up calling the run () method of the runnable when its turn comes up on the event queue. note: although a new runnable object is created here, it is executed by the message thread rather than by creating a new thread. /** Created on 2005-7-17 ** Java Thread Programming-Paul Hyde * copyright? 1999 SAMs publishing * Jonathan Q. bo Study Notes **/package Org. tju. msnrl. jonathan. thread. chapter9; import Java. AWT. *; // import Java. AWT. event. *; // don't need this packageimport javax. swing. *; import Java. lang. reflect. *; // just for 'invocationtargetexception'/*** @ author Jonathan Q. bo from tju msnrl ** E-mail: jonathan.q.bo@gmail.com * blog: blog.csdn.net/jonathan_q_bo * blog.yesky.net/jonathanundersun * * Enjoy life with sun! **/Public class invokeandwait {Private Static void print (string MSG) {string temp = thread. currentthread (). getname (); system. out. println (temp + "-" + MSG);} public static void main (string [] ARGs) {final jlabel lB = new jlabel ("_____"); jbutton bt = new jbutton ("Click here! "); Jpanel Pn = new jpanel (New flowlayout (); Pn. add (LB); Pn. add (BT); jframe fm = new jframe ("simple event"); FM. setcontentpane (PN); FM. setsize (300,100); FM. setvisible (true);/* lb. settext ("clicked"); lb. repaint (); * // automatically change the label after three seconds */try {thread. sleep (3000); print ("thread sleep 3 secs"); print ("Create a code block to run by event-thread"); runnable Runa = new runnable () {public void run () {print (" Do change label... "); lb. settext ("clicked") ;}}; print ("begin to run invokeandwait ()");/* handle by message thread */swingutilities. invokeandwait (Runa); print ("end from invokeandwait ()");} catch (interruptedexception E1) {e1.printstacktrace ();} catch (invocationtargetexception E2) {e2.printstacktrace () ;}} console output result: Main-thread sleep 3 secsmain-create a code block to run by event-threadmain-begin to run invo Keandwait () AWT-EventQueue-0-do change label... main-end from invokeandwait () do not call swingutilities. invokeandwait () from the event thread. doing so causes an instance of error to be thrown. even if this call were allowed, it wocould put the event thread into a deadlocked state. the event thread does not need the services of invokeandwait () because it can make the changes directly. do not call in the message thread Swingutilities. invokeandwait () will throw an error and cause the message thread to think about it. The message thread itself can directly change the GUI without calling invokeandwait (). Using SwingUtilities. invokeLater ()  The SwingUtilities class has another static method available to use to put references to blocks of code onto the event queue: public static void InvokeLater(Runnable target) The SwingUtilities. invokeLater () method works like SwingUtilities. invokeAndWait () blocks t for the fact that it puts the request on the event queue and Returns right away. The invokeLater () method does not wait for the block of code inside the Runnable referred to by target to execute. this allows the thread that posted the request to move on to other activities. the only difference between invokeLater () and invokeAndWait () Is that invokeLater () returns immediately without waiting for the execution of the run code to complete. In addition, this method does not throw any exceptions. You need to capture Possible exceptions within the target's run in time. Just as with invokeAndWait (), a new thread is not created when Runnable is used with SwingUtilities. invokeLater (). Similarly, executing this method does not create a new thread. /** Created on 2005-7-17 ** Java Thread Programming-Paul Hyde * Copyright? 1999 Sams Publishing * Jonathan Q. bo Study Notes **/package org. tju. msnrl. jonathan. thread. chapter9; import java. awt. *; // import java. awt. event. *; // don't need this packageimport javax. swing. *; // import java. lang. reflect. *; // just for 'invocationtargetexception'/*** @ author Jonathan Q. bo from tju msnrl ** E-mail: jonathan.q.bo@gmail.com * Blog: blog.csdn.net/jonathan_q_bo * blog.yesky.net/jonathanundersun ** Enjoy Life with Sun! **/Public class InvokeLater {private static void print (String msg) {String temp = Thread. currentThread (). getName (); System. out. println (temp + "-" + msg);} public static void main (String [] args) {final JLabel lb = new JLabel ("_____"); JButton bt = new JButton ("Click here! "); JPanel pn = new JPanel (new FlowLayout (); pn. add (lb); pn. add (bt); JFrame fm = new JFrame ("simple event"); fm. setContentPane (pn); fm. setSize (300,100); fm. setVisible (true);/* lb. setText ("Clicked"); lb. repaint (); * // * pause for three seconds */try {Thread. sleep (3000); print ("thread sleep 3 secs");} catch (InterruptedException e1) {e1.printStackTrace ();} print ("create block to run by invokelater () "); Runnable runA = New Runnable () {public void run () {// catch possible exceptions try {Thread. sleep (100); print ("set text to label"); lb. setText ("clicked! ");} Catch (Exception e) {e. printStackTrace () ;}}; print ("beigin invokeLater ()... "); SwingUtilities. invokeLater (runA); // This method immediately returns print ("end from invokeLater ()... ") ;}} console output result: main-thread sleep 3 secsmain-create block to run by invokelater () main-beigin invokeLater ()... main-end from invokeLater ()... AWT-EventQueue-0-set text to label Unlike SwingUtilities. invokeAndWait (), the event thread is permitted to call SwingUtilities. invokeLater (). however, there isn' t any value to doing so because the event thread can change the components directly. Using SwingUtilities. isEventDispatchThread ()  Public static boolean IsEventDispatchThread() This static method returns true if the thread that invokes it is the event thread, and returns false if it is not. this method tests whether the thread that calls this method is a message thread. If yes, true is returned. Otherwise, false is returned. If ( SwingUtilities. isEventDispatchThread() = False) {throw new RuntimeException ("only the event thread shocould invoke this method ");} When invokeAndWait () and invokeLater () Are Not Needed  It is not always necessary to use invokeAndWait () and invokeLater () to interact with Swing components. any thread can safely interact with the components before they have been added to a visible container. you have seen this already in the examples: The main thread constructs the GUI and then invokes SetVisible(). After the components have been drawn to the screen, only the event thread shoshould make further changes to their appearance.It is not necessary to use the invokeAndWait () method and the invokeLater () method to interact with the Swing component. Any thread can securely interact with a component before it is added to a visible container. The main thread initializes the GUI and then calls setVisible (). After the component is displayed on the screen, it should be changed only by the message thread. There are a couple of exceptions to this restriction. the adding and removing of event listeners can safely be done by any thread at any time. also, any thread can invoke the repaint () method. the repaint () method has always worked asynchronously to put a repaint request onto the event queue. and finally, any method that ExplicitlyIndicates that it does not have to be called by the event thread is safe. the API documentation for the setText () method of JTextComponent explicitly states that setText () can be safely called by any thread. the setText () method is inherited by JTextField (a subclass of JTextComponent), so any thread can safely invoke setText () on a JTextField component at any time.  There are also some special cases where any thread can add or delete message listeners at any time. Any thread can call the repaint () method, which asynchronously places the repaint request to the message queue. In addition, any explicitly declared thread-safe method that can be called by any thread is safe and can be called without the message thread. Just like the setText () method in the previous examples, in JTextComponet, it is noted that "This method is thread safe, although most Swing methods are not. please see Threads and Swing for more information ", any thread can directly call it to change the control's appearance, without calling repaint () or invokeAndWait () and so on.  If you aren't sure whether a particle method on a Swing component can be invoked by any thread, use the invokeAndWait () or invokeLater () mechanic to be safe.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.