| COMP 310 | Dynamically Modifying GUIs | 
|      | 
It is very common to want to make a GUI that is dynamically modifiable enable it to adapt to changing situations or to present different user capabilities in different situations or to augment the GUI as the system dynamically changes.
Whenever one is modifying the GUI, always remember
ALL GUI MODIFICATIONS MUST TAKE PLACE ON THE JAVA GUI ("AWT EVENT DISPATCH") THREAD!
This is not a problem if all your code takes place on the GUI thread, but one must take special care if the code that wants to do the modifications is not on the GUI thread, or perhaps is unknown as to whether it is or is not on the GUI thread.
To transfer operation over to the GUI thread, use the 
SwingUtilities.invokeLater(Runnable r) (non-blocking) or 
SwingUtilities.invokeAndWait(Runnable r) (blocking) methods.   The SwingUtilities.isEventDispatchThread() 
can be used to determine whether the current thread is or is not the GUI thread. 
invokeLater() can be called from any thread, even the GUI thread 
because it is non-blocking, but invokeAndWait() must be 
called from a non-GUI thread or it will 
deadlock the GUI, so isEventDispatchThread() must be checked first 
to insure that one is not on the GUI thread.
Recommendation: Restrict the components being created to JComponents for maximum capabilities and safety.
There are many ways to provide services that allow other parts of the system 
  to dyanamically add components, typically JComponents, to the GUI 
  in a GUI-controlled manner.  Let's compare and contrast 3 different 
  techniques for implementing the service provided by the GUI to the user's code 
  to add the user's component to the GUI:
| Technique: | Pros: | Cons: | Notes: | 
| Recommended: Give the GUI a factory that creates the desired component to 
		add: where IComponentFactory is a factory that instantiates aJComponent,  e.g.
		
	  java.util.function.Supplier<JComponent>. | Simplest method overall.   No GUI threading issues on the user side, any thread can be used.   
		Simple GUI thread dispatching on the GUI side due to the void
		return. | Seemingly more complicated as it requires the definition of the factory interface. Note that the code of the factory is really the same as the code in the other two techniques below for instantiating the desired component, it's just in a different place. The use of lambda expressions can help keep the code relatively smaller however plus help with making sure the factory has access to everything it needs (via the lambda's closure). | The void return means that the entire process of 
		preparing the GUI, instantiating the desired component using the 
		supplied factory, and installing the resultant component can all be 
		easily dispatched onto the GUI thread usinginvokeLater()with no 
		thread synchronization needed. | 
| Get a container fro the GUI to put components into: Container getContainer() | Deceptively simple looking code that can be incorporated into the process that is instantiating the desired component to add. | No guarantees that the method is invoked on the GUI thread, so GUI side code must must check the thread and then do thread synchronization if it is not the GUI thread in order to return the container (created on the GUI thread) back on the original thread. User side code must also be on the GUI thread when adding components to the container. | Effectively couples the GUI's container generation to the user's component instantiation process. | 
| Add an already instantiated component to the GUI: 
		 | Deceptively simple looking code which separates the user's instantiation of the component from its 
		installation. No thread synchronization on the GUI side needed due to void return. | Requires that the user's code properly instantiate the component on 
		the GUI thread which might not be the thread that is calling 
		addComponent(), so thread synchronization may be needed on the 
		user's side. | By always using SwingUtilities.invokeLater()to add the 
		component to the GUI, this technique can be called from any thread. | 
Don't get mislead by a seemingly "simpler" implementation by the latter two options above! The surrounding threading issues actually make their code MORE complicated and much more difficult in the end. The "factory" method completely releases the caller side from the GUI threading issues and is a very simple dispatch to the GUI event thread on the implementation (local system) side. So in the end, it is actually the simplest of all the options!
© 2017 by Stephen Wong