As we mentioned at the beginning of the book, threading considerations play a very important role in Swing. This isn’t too surprising if you think about the fact that Java is a highly multithreaded environment, but there is only a single display on which all components must render themselves in an organized, cooperative way. Some of the low-level code that interacts with peers in the native windowing system is not reentrant, which means that it can’t be invoked safely while it’s in the middle of doing something. Of course, that’s exactly what might happen if different threads interact with it! Because of this fundamental limitation, there would have been no real benefit to undertaking the major effort of making the Java methods in the Swing components themselves thread-safe—and indeed, with few exceptions, they are not.
In order to address this issue, Swing requires that all activity that interacts with components take place on a single thread, known as the event dispatch thread. This also allows Swing to consolidate repaints and otherwise improve the efficiency of the drawing process.
This restriction actually takes effect only after a component is
realized, meaning that it’s been painted on-screen
or is ready to be painted. A top-level component is realized when it is
made visible or has its
pack( ) method called. At that point, any components it contains are also realized, and any components added to it later are immediately realized. This does mean, ...