This assignment has two main parts: Click Program Behavior to the left for an example of one approach to this assignment. Note: Before you start, use NetBeans to copy your CS_2511_GUI project from the previous assignment to a new NetBeans project called CS_2511_Framework_Graphics (right click the project node in the Projects window and select Copy...).
You will add to the framework and application domains (bridge and water jug problems) as described in this section.

Suggestion:

  • Ignore the issues brought up by the animation requirement until after you have successfully implemented and tested the system for graphical presentation without animation
  • Then revisit the animation issue by following the hints given later
The framework needs another abstract class Canvas to represent the object on which to paint graphical renderings of states.

This section suggests the way to do this.

After the previous assignment, your top-level framework structure should look like that shown in the class diagram below.

A natural way to incorporate Canvas is to associate it with GUI:

  • Should extend JComponent
  • Should be declared to be abstract
    • No abstract methods, but
    • Must be subclassed to override the paintComponent method
  • Constructor should take the first State object displayed by the canvas and store it
  • Should provide accessor and mutator for the state being displayed
  • It may help to also provide an accessor and mutator for the previous state to carry out animation
  • This class can also have any methods that might be generally useful to subclasses
  • Constructor should take a Canvas object as its second argument and store it (along with the Problem argument from before)
  • The canvas, being a JComponent, should be added to the GUI layout instead of the JTextArea from before
  • In the move button listeners, if doMove is successful:
    • The canvas must be told about the new state
    • The canvas must be repainted
  • Similar actions must be taken upon problem reset
Your bridge and waterjug packages need classes that extend Canvas.

Suppose they are BridgeCanvas and WaterJugCanvas, respectively.

For both BridgeCanvas and WaterJugCanvas:
  • Constructor should accept the appropriate initial state and pass if off to the Canvas constructor using super
  • Constructor should create and store any drawing objects that are needed by paintComponent
  • paintComponent should draw the objects required to depict the problem's current state
  • When using the setColor method (from java.awt.Graphics), you can create arbitrary colors using the Color constructor (from java.awt) taking three integers representing red, green, and blue values
  • Here is a useful resource for finding suitable red, green, and blue values: RGB Color Chart
  • To accurately position text on your canvas, see the special topic on page 163 of the text
  • Use the GeneralPath class (from java.awt.geom) to draw arbitrary shapes:
    • Create a path using new GeneralPath()
    • Determine a point (x0,y0) that is the start of the drawing
    • Move to the start using path.moveTo(x0,y0)
    • Determine the remaining points on your drawing (x1,y1), . . . (xn,yn).
    • Draw a line to (x1,y1) using path.lineTo(x1,y1)
    • . . .
    • Draw a line to (xn,yn) using path.lineTo(xn,yn)
    • Complete the drawing back to (x0,y0) using path.closePath()
  • The above procedure draws a closed figure with straight edges. To incorporate curves, replace calls to lineTo with calls to quadTo
  • A useful tutorial: Working With Java 2D Graphics
You can test your graphics only, in isolation from your GUI.

Or, you can test your GUI with graphics included.

Add the following main method to your BridgeCanvas class:
    public static void main(String[] args) {
        JFrame frame = new JFrame("BridgeCanvas Test");
        frame.add(new BridgeCanvas(new BridgeState(Position.WEST,
                                                   Position.WEST,
                                                   Position.WEST,
                                                   Position.WEST,
                                                   Position.WEST,
                                                   0)));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

Now run the BridgeCanvas.java file to observe the rendering of the state.

Change the states given to the BridgeCanvas constructor to observe different states.

Follow the same procedure with your WaterJugCanvas class.

GUIs are constructed by three classes that you have copied over from your previous assignment:
  • BridgeGui (in the bridge package)
  • WaterJugGui (in the waterjug package)
  • TestFrame (in the framework.test package)
Since you have added a second parameter of type Canvas to the GUI constructor, you need to add the appropriate parameter to each of the new GUI(...) calls in these test files.

Once that's done, you can run these files and they should behave as before but with the graphical rendering of states.

Use the Timer class (in javax.swing) to successively draw an object in a new location and repaint the canvas on which it is drawn.

See the animation example on pp. 164—169 of the text for details on how a timer is used to produce animation.

The rest of this section treats issues specific to this assignment.

  • The successive redrawing of the shape(s) cannot be done from within the Canvas object's paintComponent method itself
  • So management of the timer must be done by some other method, call it for example render, that will have to be added to the abstract Canvas class, and which will have to be overridden by any class that wants to do animation
  • The GUI's move button listeners will have to call render rather than repaint
  • Classes that don't perform animation can simply have their render methods call repaint
To the right is a sequence diagram showing the suggested interaction of the canvas, timer, and timer listener objects.

Suppose you are animating the filling of a water jug.

  • By initDrawCriteria is meant the initializing of the height of the rectangle representing a water jug.
  • By updateDrawCriteria is meant the incremental change needed to the height of the rectangle in order to carry out the animation.
  • Due to the way a timer works, the firing of the actionPerformed method and updateDrawCriteria actions are executed in a loop.
  • It is up to the timer listener to determine if the animation is finished and to either stop the timer or repaint the canvas accordingly.
When your program is working correctly you will submit your entire Netbeans project, but first:
  • To double-check that everything is in order, click Build on the menu bar and select Clean and Build Main Project.
  • Run the bridge.BridgeGUI and waterjug.WaterJugGUI classes to make sure everything works.
  • Run the framework.test.TestFrame class to be doubly sure.
Outside of NetBeans, zip your project folder as your-login-PA4.zip.

Email the zip file to your TA.

  • Correctness, appearance and creativity of static graphical renderings: 20 points
  • Successful incorporation of animation: 10 points