Step 2


Introduction

For custom graphics, you normally need to implement the paintComponent() method in a subclass (a class that extends) JPanel. You already have a preliminary definition of the FractalPanel class as a subclass of JPanel. In this step, you will write the paintComponent() method for that class.

A fractal has a basic pattern that is repeated many times with different locations, orientations, and sizes. The basic pattern for your fractal is called a branch. Since the basic pattern is repeated many times, it is helpful to have a method for drawing it, with parameters for controlling its location, size, and orientation. In this step, you will write a drawBranch() method for this purpose.

For this step, a branch is just a straight line. Your drawBranch() method is invoked four times from the paintComponent() method at four different angles, resulting in a cross shape. In the last step of this programming assignment, you will modify the drawBranch() method to draw a complete fractal branch.

All of the modifications in this step involve adding code to the FractalPanel class. You should begin by adding some instance variables for contolling the fractal drawing.

Adding Instance Variables

The FractalPanel class should have the following integer (int>) instance variables for controlling the fractal pattern.
Variable Initial Value
angle 0
length 100
levels 3

Since these are instance variables, they can be placed anywhere in between the braces of the class definition except inside methods or constructors.

The paintComponent() Method

The definition of a paintComponent() method should always have the following form.
    public void paintComponent(Graphics g) {
	super.paintComponent(g);
	drawing commands
    }
Here, drawing commands is a sequence of statements that send drawing messages directly or indirectly to the parameter g. You have already seen examples of drawing commands for changing the color and drawing a string in the text applet programming assignment.

For the FractalPanel class, your paintComponent() method should just set the color to blue, then draw 4 branches starting at the center of the panel. Each branch is drawn by calling the drawBranch() method. The rest of this section describes how to write code for these method calls.

The calls to drawBranch() all use the paintComponent() g parameter as their first parameter. The next two parameters are the coordinates of the center of the fractal panel. The center has x-coordinate getSize().width/2 and y-coordinate getSize.height()/2). Since you are making four calls, it it helpful to define two variables centerX and centerY inside the paintComponent() method. For example, the statement for the centerX variable is

    int centerX = getSize().width/2;

Variables that are defined inside a method are called local variables. They can only be used inside the method in which they are defined, and they must be defined before they are used (that is, higher up in the code).

The length and levels variables should be passed for the len and lev parameters of drawBranch(). The only difference in the four calls is the ang parameters, which should be angle, angle + 90, angle + 180, and angle + 270. For example, the statement for the first call should be

    drawBranch(g, centerX, centerY, angle, length, levels);

Writing the drawBranch() Method

The FractalPanel uses the drawBranch() method to draw a basic pattern of the fractal. It is called by the paintComponent() method, described above. It has a Graphics parameter g (obtained from the paintComponent() Graphics parameter) and 5 integer parameters:
x the starting x-coordinate of the branch
y the starting y-coordinate of the branch
ang the angle of the branch
len the length of the longest line in the branch
lev the number of repetition levels of the branch

When you are writing a method with parameters, the parentheses after the method name should contain a comma separated list of typed parameters. A typed parameter consists of the parameter type (Graphics or int for the parameters) followed by the name of the parameter. For example, the definition for the drawBranch() method should look like

    public void drawBranch(Graphics g, intx, int y,
			   int ang, int len, int lev) {
	method statements
    }
Here, method statements is a sequence of statements that are executed whenever the method is called.

Your drawBranch() method should just draw a straight line of length len from the point (x, y) in the direction of ang. The line is drawn by sending a drawLine() message to the Graphics object g. There are four parameters required for this message: the x- and y-coordinates of the starting point of the line and the x- and y-coordinates of the end point of the line.

The coordinates of the end point are computed by the following code.

    int newX = x + (int)(Math.cos(Math.PI*(double)ang/180.0)*len);
    int newY = y + (int)(Math.sin(Math.PI*(double)ang/180.0)*len);
This just defines two local variables that can be used as the last two parameters in a drawLine() message sent to the Graphics object g. Thus the drawLine() message is coded by the following statement.
    g.drawLine(x, y, newX, newY);

Testing Your Modifications
When you have finished with the modifications in this step, you should recompile FractalPanel.java and run the applet with appletviewer. You should get the same appearence as the following demonstration applet.

Demonstration Applet

If it looks the same then you are ready to validate your lab exercise with the TA. If you have time left, then you can work on Programming Assignment 2, which continues from where this lab exercise left off.