Model-View-Controller (MVC)

Java Graphics Basics



I. Sample Program and MVC

The current directory 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.  This window has 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.

mvc.png (22290 bytes)

In the above diagram, class BPList is the model.   It represents the list of body parts, each of which is a concrete implementation of the Drawable interface.  An interface, in Java, is a special construct that is similar to an abstract class.  All the methods in an interface are purely abstract, that is they have no code body.  In addition, an interface cannot have non-static fields.  Java uses interface as way to allow a special form of multiple inheritance, which we not discuss for now. 

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 actionPerformed (ActionEvent e) 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 the left panel of the BodyPartsGUI object, and one for the right panel of the GUI.  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 source code for BPControl provided is incomplete. 

 

II. Basic Java Graphics

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 paintComponent (Graphics g), you almost always call super.paintComponent (g) in order to get 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 (Graphics g) 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 created in a very special way: it does not have a name and exists only in the context of an instance of BPControl!   As such, it is called an anonymous inner class of class BPControl.

_frame.get_jButtonLeft().addActionListener (
    new java.awt.event.ActionListener()  // NOTICE the use of anonymous inner class here!
    {
        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'.

swing.png (12190 bytes)

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.

dxnguyen@cs.rice.edu
revised 10/04/00