The current directory
(~comp212/public_html/01-spring/notes/lecture-16/
)
contains the Java source code and byte code for a GUI application
that (almost) meets the requirements of milestone #2 of project #1.
To see how the application behaves, run the command
java OldBPControl. You should see a window appear with two main panels: a left (west) panel and a right (east) panel. Each panel has a button at the top (north) and a graphics a panel at the center. If you click on the left button, you should see body parts moving to the right. If you continue to click when there is no more body part, you will see an exception thrown. Click on the right button and you should see the body parts move to the left. Play around with this program and record its behavior. The program is designed according to what is called the Model-View-Controller (MVC) pattern as shown in the UML diagram below.
Class BPList
is the model.
It represents the list of body parts, each of which is a concrete
implementation of the Drawable
interface.
BodyPartsGUI
contains Java GUI (graphical user interface)
components to display the model BPList
and to allow the
user to interact with it by clicking a couple of buttons.
When a user clicks a button, the Java virtual machine fires an event,
called ActionEvent
, and delivers it to this button.`
In order to be able to sense this event and do something useful,
the button must have an ActionListener
object attached to
it. You attach an ActionListener
to a GUI component by
calling addActionListener(...)
on the GUI component
(see code sample in the next section). An ActionListener
responds to the ActionEvent
object it receives by
executing its
public void actionPerformed(ActionEvent e)method. The programmer writes the code for this method to carry out the desired task.
The wiring between a GUI component and the model is called a control.
In the above example, the main control, BPControl
,
references two BPList
objects, one for each panel of
the BodyPartsGUI
object. It is in this control that
we install all the event listeners for each of the GUI components
in the view (BodyPartsGUI). The action listener for the left
button handles the click button event by asking the left BPList
to remove one body part from the front of the list and then asking
the right to insert it at the end. The listener for right button
does the reverse. The provided source code
for BPControl
is incomplete.
The simplest to draw graphics in Java is to extend JPanel
,
a Swing component, and override its
paintComponent(Graphics g)method in order to draw on the graphics object g. Whenever Java tries to render a Swing GUI component, it calls the component's
paintComponent(Graphics g)
method with the current
graphics context as the parameter. In the code for this method,
you almost always call super.paintComponent(g)
to do whatever the parent's class said paintComponent(g)
should do, including using the correct internal
(hidden) rendering sequence. The code for BodyPartsCanvas
illustrates this process. BodyPartsCanvas
is where
the list of body parts, BPList
, draws itself. The
view, BodyPartsGUI
, contains two instances of
BodyPartsCanvas
in order to draw the two lists of body parts.
public class BodyPartsCanvas extends JPanel { // Other fields and methods... // ... public void paintComponent(Graphics g) { super.paintComponent(g); // code to draw on g.... } }
You never call paintComponent()
directly.
Instead, you should call repaint()
to let Java
schedule the repaint process and properly call paintComponent()
.
This is illustrated in the code for the action listeners for the left button
in BPControl
. The ActionListener
object attached to the left button in the view is typically created
as an anonymous inner class.
_frame.get_jButtonLeft().addActionListener( new java.awt.event.ActionListener() // anonymous inner class! { public void actionPerformed (ActionEvent e) { // code to manipulate _rightBPList and _leftBPList here _frame.get_pnlBodyPartsLeft().repaint(); // redraw the left body parts list _frame.get_pnlBodyPartsRight().repaint(); // redraw the right body parts list. } });
Below is a UML diagram displaying a partial taxonomy tree for Java GUI components. We are only interested in working with Swing components. The Swing components all start with a capital 'J'.
Note that JPanel
extends JComponent
,
which extends Container
. So
>JPanel
is a Container
and can contains any AWT/Swing component.
This is an example of the composite pattern.