Step 1


Overview

For the first step, you will write preliminary class definitions for the DrawPanel and GraphicsApplet classes. These preliminary definitions might appear to be a little bit contorted, but they are serving three important purposes:

Each of these purposes are discussed in more detail in the next three sections. These sections describe certain aspects of the finished program. They are not instructions for doing the first step. The instructions for the first step are in later sections.

Making the Draw Panel and Graphics Applet Aware of Each Other

This programming assignment is similar to the previous assignment. Both have a control panel defined in the applet class (FractalApplet or GraphicsApplet). Both have a graphics display panel class (FractalPanel or DrawPanel).

However, communication is handled differently in the two assignments. In the previous assignment, the controls sent information to the graphics display panel by invoking its setter methods, such as setLevels(). For this assignment, the controls just tell the graphics display panel to update itself by invoking an updateDrawing() method defined in the DrawPanel class. Then the graphics display panel asks the applet about anything that it needs to know in order to do its drawing. It does this by invoking getter methods, such as getX(), defined in the GraphicsApplet class.

To make this work, you must define an instance variable in each class that refers to an object from the other class. A GraphicsApplet object needs a DrawPanel instance variable so it can tell the draw panel to update itself. A DrawPanel object needs a GraphicsApplet instance variable so it can invoke its getter methods.

Typically, an applet constructs other components in its init() method. This makes it easy to get an instance variable in the GraphicsApplet class that refers to a DrawPanel object. But how does the DrawPanel object get a reference to the DrawPanel object? The simplest answer is to design the DrawPanel constructor with a GraphicsApplet parameter. When the GraphicsApplet constructs its DrawPanel, it passes itself as the value for the parameter. In the constructor, the parameter is assigned to an instance variable. Then both objects can send messages to each other.

There is an unfortunate side effect to this kind of communication: neither class can be compiled unless there is at least a preliminary definition for the other. When the compiler encounters a DrawPanel variable definition in the GraphicsApplet class, it checks for a definition of the DrawPanel class. If it doesn't find one then you get an error message. Conversely, When the compiler encounters a GraphicsApplet variable definition in the DrawPanel class, it checks for a definition of the GraphicsApplet class. Again, if it doesn't find one then you get an error message.

Putting a Titled Border Around the Draw Panel

For this assignment, you will put a titled border around the draw panel. The title in the border displays something like
    g.drawString("Hit return after changes.", 100, 100);
In this assignment, the title is supposed to change when the user operates the controls. Thus borders are handled differently than in the previous assignment. A titled border is an instance of the TitledBorder class in the javax.swing.border package. This class has a setTitle() method for changing the title. You could not use this if the border were set up as in the previous assignment because there wouldn't be a variable that could serve as the receiver of a setTitle() message. Thus for this assignment, the graphics drawing panel has a TitledBorder instance variable.

The most natural thing to do is install the border onto the drawing panel. Unfortunately, borders are installed inside the component that they are installed on. This means that the points with x-coordinates or y-coordinates near 0 are inside the border. To prevent overlap between the drawing and the title, you need an outer panel around the drawing panel. The drawing panel is added into the outer panel. Fortunately, layout managers are aware of borders so they will place the drawing panel inside the border.

This does, however, create a problem for the GraphicsApplet class. It has a variable that refers to a DrawPanel. If it adds that variable directly to its content pane then the outer panel will not show up. To solve this problem, the DrawPanel class has a getOuterPanel() method that returns its outer panel. This method is invoked in the GraphicsApplet class and the return value is added to the content pane.

Getting Some Organization into the Construction and Layout

Applet init() methods tend to get clumsy for applets that have a lot of components. This clumsiness can be reduced by using helper methods for constructing and configuring components or groups of components. Then the init() method just invokes the helper methods. This makes the code easier to understand and makes it easier to determine where you need to make changes when something goes wrong.

For this assignment, you will use four helper methods in the GraphicsApplet class.

The createSlider() helper has an additional advantage. You write code once for creating and configuring JSlider. Then you only need one additional line of code to create each of the eight JSlider controls.

The Preliminary Definition for the DrawPanel Class

For the DrawPanel class, you should have three instance variables, described in the following table.
Type Name Initialization
GraphicsApplet applet null
TitledBorder border BorderFactory.createTitledBorder("TBA")
JPanel outerPanel new JPanel()

The constructor for the class should have a parameter of type GraphicsApplet. The first line of code in the constructor assigns this parameter to the applet variable. The preferred size should be set to 400 by 400. Then you set the background color to white, set the border of the outer panel with the border variable, set its layout manager with a BorderLayout, and add the draw panel to the center of the outer panel. The statement for the last part is

    outerPanel.add(this, BorderLayout.CENTER);
The Java keyword this refers to the object that you are writing code for, a DrawPanel instance in this case.

The last thing you need in the class is a method for getting the outer panel. The code for this is Its return type is JPanel and its name is getOuterPanel. It has no parameters. It contains a single statement that returns the outerPanel variable.

The Preliminary Definition for the GraphicsApplet Class

For the GraphicsApplet class, you will initially have just one instance variable, a DrawPanel named drawPanel that is initialized using the DrawPanel class constructor. The constructor parameter is the GraphicsApplet object that you are writing code for (this).

Before writing the init() method, you need a helper method for constructing and configuring the control panel. Begin with the following code.

    JPanel createControlPanel() {
	JPanel controlPanel = new JPanel();
	controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
	return controlPanel;
    }
This is similar to most method definitions that you have written except that the keyword public is missing at the beginning. Helper methods are intended for use only inside the class in which they are written. You only need the public keyword for methods that are used outside the class.

Now you will need to add two lines of code to set the minimum and preferred sizes of the control panel to 160 by 400. These should be added just before the return statement.

For now, you are done with this helper method. When controls are added in later steps, you will add a line of code for each control.

Finally, you need to write the applet init() method. You only need two lines of code in it that add a controlPanel (use createControlPanel()) and the outer panel of the draw panel (drawPanel.getOuterPanel()) to the left and center parts of the applet's content pane. Since the content pane has a BorderLayout by default, you will not need to set the layout manager.

After you have completed preliminary definitions of both classes then you should compile them to check for syntax errors.

The GraphicsApplet.html File

As usual, you will need an HTML file to use with appletviewer. This file should be like the HTML files in the previous programming assignments except for the title, class name, and dimensions. The dimensions should be 570 by 425.

Testing Your Applet

When you run applet with appletviewer, it should look like the following demonstration applet.

Demonstration Applet