Notes from Swing & Threads Talk
By Adrian Sutton
Notes from the session on Swing and Threads. Unchecked etc.
Using Threads Correctly And Effectively Todays modern application – many inherently latent sources. Talking to these sources nessecetates threads. Main thread – thread that calls main Event Dispatch Thread – dispatches java level AWT events Toolkit Thread – Dispatches events from windowing system In Applets: Multiple applets have multiple threads in teh same process. Actually depends on class loaders. Each applet has a dispatch thread. Also has an applet thread that calls start/stop/init Toolkit thread interfaces with native windowing system. Two Big Rules of Java Technology GUIs – Never invoke swing methods or swing code from anywhere but the EDT. – Swing is not thread safe. – AWT is thread safe. Can be called from multiple threads. – Avoid performing long operations (anything that may end up blocking, fileIO, socket IO etc) – Offload to a separate thread – SwingWorker will help do this. Recommended Application Structure public static void main(String[] args) { JFrame frame = … <- Creating component on main thread not EDT. frame.pack(); frame.setVisible(true); } Recommend putting GUI loading into a runnable and call using invokeLater. Why you should creat eGUI on EDT Event dispatch thread is created as needed and is not under your control. Created when there are events on teh event thread. Don’t know when events are created. Listeners may be notified before you have finished creating the GUI. Some JFC/Swing API-based components use invokeLater if not called on event dispatch thread, resultin gin multiple threads accessing same component. Advanced App Startup - Show splash screen immediately from main thread using only AWT. (AWT is thread safe) - Use invokeLater to load remainder of UI - Break loading into small pieces interspersed with paint calls to splash screen. - Consider loading classes that will be needed before you show the UI to improve perceived performance. - Use -verbose to determine classes that are required. - Update progress calls splashscreen’s paint directly. Handling Lengthy Tasks Pushing too many runnables onto the EDT may get clogged. Can delay UI updates to coalase results. Can schedule updates to the user interface. Need to handle partial and final results on the event dispatch thread. notify property change listeners on EDT. Track status on EDT. Using java.lang.reflect.Proxy Can be used to seamlessly invoke methods on the EDT from another thread. spin.sourceforge.net is built on this. Can also be used to detect when the model is sending out a notification from threads other than event dispatch threads. Use proxy to generate implementation of interface. * Invocation handler will use invokeLater to invoke method on EDT * Consumers continue to directly invoke method on object without worrying abuot thread. Automating Use of ModelListener Can register a ComponentUI. UIManager.put(“TableUI”, “ModelListener”); public static ComponentuI createUI(JComponent c) { addListener(((JTable)c).getModeL()); // Attach a property change listener to listen for model changes etc. return UIManager.getLookAndFeelDefaults().getuI(c); } Threading Gotchas Avoid overwhelming event dispatch thread. Happens when invokeLater is called too often. Can create a coalescing runnable to avoid this. Can check for this happening by periodically posting a runnable to the event dispatch thread and checking how long it takes to execute. Suggested posting a Runnable every 1 minute. Future Combine Toolkit/EDT threads -Improve performance of event dispatching -Some toolkits require that painting occurs on the toolkit thread. This requires a bunch of thread synchronizations and can cause serious performance problems. Developer controlled event dispatching - Start event dispatch thread from main. Foxtrot/Spin - Both centre around how modal dialogs are implemented. Modal dialogs block EDT but spawn a new EDT. Splash screen helper - Provide a SplashScreen class or command line args to show a splash screen. - Possibly create an application class that you instantiate and call run on. Integrating SwingWorker into the core. foxtrot.sourceforge.net jdnc.dev.java.net javadesktop.org