
         Event Driven GUIs

For an event driven GUI program, we must instantiate four kinds of
objects. There must be (at least) one object that is a source of
GUI events. There must be (at least) one object that is registered
to handle the GUI events generated by the event source. There must
be (at least) one object that holds "state" information about our
GUI. And there must be (at least) one object that uses the state
information to repaint the GUI.

In addition to the four kinds of objects that we must instantiate,
the JVM will instantiate a fifth kind of object. When an event occurs,
the JVM will instantiate an Event object that encapsulates information
about the event. This Event object gets passed to each object that is
registered to handle the event.

The main idea is that when an event handling method is called (by the
JVM, see below for details) to handle a GUI event, the handler should
use the information in the Event object to update the GUI state object
(this requires a mechanism for the event handler object to communicate
with the GUI state object). After the event handler has updated the GUI
state object, the event handler needs to notify the object that repaints
the GUI (this requires a mechanism for the event handler object to
communicate with the GUI repainting object). Then the GUI repainting
object needs to examine the GUI state object and use that information
to update the way the GUI looks (this requires a mechanism for the GUI
repainting object to communicate with the GUI state object).


  Event source object
+----------------------+
|                      |       List<EventListener>
| List<EventListener>--|------->+------+
|                      |        |      |           EventListener object
|                      |        +------+         +----------------------+
| addListener()        |        |  ----|-------->|                      |
+----------------------+        +------+         | handleEvent(Event e) |
An object that generates        |      |         | {                    |
events and receives Event       +------+         |    ...               |
objects from the JVM.                            | }                    |
                                                 |                      |
                                                 +----------------------+
     Event object                                An object that implements
  +-------------------+                          the EventListener interface.
  | Created by JVM    |
  | using information |
  | from the OS about |     Program state object           GUI object
  | an event          |    +----------------------+     +------------------+
  +-------------------+    |  Information about   |     |                  |
                           |  the current state   |     | paintComponent() |
                           |  of the GUI program. |     | {                |
                           |  This needs to be    |     |    ...           |
                           |  updated when a GUI  |     | }                |
                           |  event occurs.       |     |                  |
                           +----------------------+     +------------------+
                                                        GUI object that needs
                                                        to be repainted after
                                                        an event occurs.


If we compare the above picture to the Model-View-Controller design
pattern, then the state object is the Model, the GUI object that needs
to be repainted is the View, and the listener object is the Controller.
The event source object can be thought of as part of the Controller.
Notice that, even though the event source may be part of the GUI (for
example, a button), it should be thought of as part of the Controller,
not as part of the View (that is, some parts of the GUI might be part
of the Controller, some parts of the GUI might be part of the View, and
some parts of the GUI might be part of both the View and the Controller).


We mentioned above that these objects need to interact (communicate) with
each other. The Controller needs access to the Model and the View. The View
needs access to the Model. Giving these objects some kind of access to each
other ends up being an important design issue in a GUI program. There are
several ways to provide this access. The most basic way is to let each
object hold a reference to any other object it needs access to (the
reference is usually provided in a constructor call). A more subtle way
is to put the definitions of the classes within the scope of each other
using either nested classes, inner classes, or anonymous classes (for
details, see the examples in the folder called how_to_handle_handlers).


Here is a diagram of the communication between the Controller, the Model,
and the View.

                       +-----------------+
                       |                 |
                       |      Model      |
                       |                 |
                       +-----------------+
  4. View queries the   /               \
     Model and then    /                 \  2. Controller updates
     repaints itself. /                   \    the Model.
                     /                     \
        +-------------+                  +----------------+
        |             |                  |                |
        |    View     |<-----------------|   Controller   |
        |             |  3. Controller   |                |
        +-------------+     notifies     +----------------+
                    \       the View.      /
       5. User sees  \                    /  1. User interacts
          repainted   \                  /      with the Controller.
          View.        \                /       (The JVM sends an
                        +--------------+         Event object to the
                        |              |         Controller.)
                        |     User     |
                        |              |
                        +--------------+




   The Life of an Event, From Mouse to OS to JVM to Component

When you click the mouse, the OS notices the mouse click "event"
since the OS owns all the hardware devices.

The OS knows what pixel the mouse was clicked on. The OS keeps a
data structure that lets it know which process owns the window at
that pixel. The OS sends a message to that process telling it that
there was a mouse click at the given pixel in its window.

In our case, the process that owns the clicked on pixel is the JVM.
So the OS tells the JVM that one of its pixels was clicked on. The
JVM translates the coordinates of the clicked on pixel from the OS's
screen coordinates to the coordinates of the window owned by the JVM.
The JVM keeps a data structure that lets it know which GUI component
owns each pixel in its window and whether or not that component has
an event listener attached to it. If so, the JVM sends a message
(with an Event object) to the listener object attached to the GUI
component that owns the pixel that the mouse was clicked on. To our
Java program, that GUI component seems to be the source of the mouse
event, not the mouse itself.

The JVM receives from the OS what we refer to as "low level events",
like "mouse moved", "mouse button pressed down", or "mouse button
released". The JVM will often translate these low level events into
"higher level events". For example, when the mouse moves into one of
the JVM's windows, the JVM will translate the "mouse move" event into
a "mouse entered" event. Similarly, when the mouse moves out of the
JVM's window, the JVM creates a "mouse leave" event.

If the component that was clicked on is, say, a JButton, then our Java
program does not actually get a "mouse clicked" event from the JVM.
Instead, the JVM translates the "low level" MouseEvent into a "high
level" ActionEvent. Most GUI components actually get "high level"
events, like ActioEvent, ItemEvent, AdjustmentEvent, or TextEvent.
These high level events convey more "meaning" to a program than low
level events like "mouse clicked". However, the JPanel and JFrame
containers are components that only receive low level events (or
"lower level" events like "mouse entered").

When the JVM sends a message (with an Event object) to the clicked
on component, the JVM doesn't actually send the message to the GUI
component object. Instead, the JVM sends the message to an "event
listener" object that is registered with the GUI component. This is
a "separation of concerns" Object-Oriented-design choice. The GUI
component's job is to appear a certain way. We do not want to give
the GUI component the added responsibility of "acting" a certain way.
We separate the "behavior" part of the GUI component into a separate
object (the event listener) that has the responsibility of implementing
the GUI component's actions. This design allows us to do things like
make a button change its behavior as a program executes. Also, we can
give a button multiple behaviors or we can add/remove behaviors from
a button as a program executes. We often say that the GUI component's
behavior has been "delegated" to the event listener object (this
terminology is used a lot by Microsoft in the C# language).


When you click the mouse on a GUI component that has a registered
MouseListener, one of the methods in that MouseListener object gets
called by the JVM. Notice that the methods in the MouseListener
object are not called by any of our code. If you look at the code
for an event driven program, you will see many methods defined in
the code that are never called from within the code. We write these
(event handling) methods but we never call them. Normally, that is
not how we write software. We tend to write methods in our code that
can be called by other methods in our code. In an event driven GUI
program we write methods that will be called by the "GUI framework".
The idea that we write methods but we don't call them (they get called
by someone else) is referred to as "inversion of control" (IoC). When
our GUI program is running, it is the Java GUI framework that is really
in control, not our code. After our code has instantiated all the
necessary objects described above (in the MVC pattern) our code
terminates and leaves the Java GUI framework in control (if you look
at any of our GUI program, you will se that the main() method returns
after it has instantiated all the needed objects, and yet, our program
does not terminate). The Java GUI framework waits for events (from the
operating system) and then calls our event listener methods as needed.
When our event listener methods return, they are returning to the Java
GUI framework, not to any code that we wrote. We say that control has
been "inverted" from our program to the Java GUI framework. Another
term used to describe the methods in listener objects is "callback
functions". This is an older term used in the C language. The idea is
that we provide these functions to the GUI framework so that it can
"call back" on these functions as events happen.


As was mentioned in the last paragraph, when the main() method of a Java
GUI program returns, the program does not terminate. Instead, control
shifts to the Java GUI framework. We can be more specific about this
shift of control. All Java code runs in some thread. When you launch a
Java program, the JVM starts a thread to run your main() method. The
thread that runs the main() method is often called the "main thread".
Unless you launch more threads, the main thread will be your program's
only thread. When main() returns, the JVM terminates the main thread and
then your program terminates. But in a Java GUI program, as soon as you
make some GUI component visible, the JVM launches a new thread, the
"Event Dispatch Thread" (EDT). This thread is how the JVM waits for
events from the operating system and it is this thread that calls your
event handling methods. So after the main() method returns and terminates,
the EDT continues to run and receive events from the OS. So the "inversion
of control" happens on the Event Dispatch Thread.


https://docs.oracle.com/javase/tutorial/uiswing/events/index.html
https://docs.oracle.com/javase/tutorial/uiswing/events/intro.html
https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html

https://math.hws.edu/javanotes-swing/c6/s3.html
https://math.hws.edu/javanotes-swing/c6/s4.html
https://math.hws.edu/eck/cs124/downloads/javanotes9-swing-linked.pdf#page=300

https://runestone.academy/ns/books/published/javajavajava/java-event-model.html
http://www.cs.trincoll.edu/~ram/jjj/jjj-os-20170625.pdf#page=614

https://www3.ntu.edu.sg/home/ehchua/programming/java/J4a_GUI.html

https://en.wikipedia.org/wiki/Model-view-controller

https://en.wikipedia.org/wiki/Inversion_of_control

https://en.wikipedia.org/wiki/Software_framework

https://en.wikipedia.org/wiki/Event_dispatching_thread
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

https://learn.microsoft.com/en-us/dotnet/csharp/delegates-overview
https://en.wikipedia.org/wiki/Delegate_(CLI)

https://en.wikipedia.org/wiki/Callback_(computer_programming)
