Introduction to Computer Graphics and Java Programming for Artists


School of the Museum of Fine Arts ::: Continuing Education

George Aroush, instructor


Lecture Four -- Writing Methods


 

Readings

  1. The handouts named:
  2. Sample Programs in Batch Four:
  3. "Java How to Program" by Paul J. Deitel, and Harvey M. Deitel

 

Exercises

    Do before our next lecture

  1. Write a program that has at least one method which will take advantage of passing and returning a value to the caller method.

For this exercises, if you wish, you can start with an applet you have already written; use the editor to cut a block of statements and insert the block in the program after paint()'s final curly brace then make up a name for the method. Don't forget to give the method a return data type (either void or int for now). Finally, call the method from inside paint() where you removed the original block. This should get you off to a good start.


Back to the top of this page. Back to main Index

 

A short cut to Incrementing and Decrementing variables

Incrementing and Decrementing

Java has many concise ways of doing common operations. One of the most common is to add or subtract 1 from a variable:

x = x + 1;

or

y = y - 1;

Java allows you to do those both statements with: ++, the increment operator and --, the decrement operator like this:

x++;

is the same as:

x = x + 1;

and

y--;

is the same as

y = y - 1;

There is less typing involved, the statements will execute faster, and you can use them in the middle of a statement or function making thing easier to read and see at a glance:

g.drawRect(x++, y, 10, 10 ); /* set pattern to k and increment k */

If ++ and -- come after the variable name, the variable's value will be used first, and then changed; we can also use ++x and --q; when the operator comes first, Java will increment or decrement the variable, then use its value in the statement in which it appears.

Java's final keyword

Java programs are often clearer and easier to modify if we define some constants at the start of the Applet:

final int MAX_X_RES = 639;

The keyword final will give the identifier MAX_X_RES the value 639, permanently. It is customary, but not required, to put names of final data types in upper-case so that to distinguishes them form standard variables. Here, MAX_X_RES is intended to indicate the right edge of the screen; if later, we wanted to get the program to work with a higher resolution screen with a right edge of 799, we could change

final int MAX_X_RES = 639;

to

final int MAX_X_RES = 799;

This change would take effect throughout the program.

Using this constant also tells a reader of the program something of the significance of a number:

if ( x > MAX_X_RES )

is more informative than:

if ( x > 639 )

Yes we could have achieve the above without the use of final, but using it will not just signal to the reader that we have a non-modifiable element, but it also can eliminate possible bugs that result in accidentally modifying it in our code later on and it also allows the Java compiler to treat it in a special way which results in a faster code.


Back to the top of this page. Back to main Index

 

Creating Methods

Why create Methods?

If you have grown weary of typing the same chunks of program code over and over, here is the answer to your prayers: methods. Methods allow us to isolate a chunk of code and use it over and over again from different parts of our program. They also make our programs easier to read and are essential for the construction of large, complex programs. The methods we write can become part of our personal library of methods which we will use them again and again -- somewhat like making our own tools, in fact that's what a method is.

The simplest method

A method consists of a method-name followed by parentheses; the parenthesis can contain values called arguments that are passed to the method -- some methods have no arguments. Some methods perform calculations and transmit or return their results to the caller. Methods can themselves be made of more primitive methods. This, we will soon see is the key to doing larger scaled work in programming.

BounceFour.java is a program that bounces a square off the four sides of the screen. It consists of two methods:

paint()

and

Sleep()

Sleep() is a method that waists time so that we get a way to control the drawing speed of our program. It allows us to introduce delays between frames. Sleep() takes no arguments (has no inputs) and returns no value. Since it doesn't return a value, it is of return type void, and thus it is declared as:

void Sleep()

Here we have void, a keywords, followed by the method name, a name we give to our method, and followed by parentheses, allowing us to pass parameters to the method if any. There is NO semicolon at the end of a method name when we create. Note that we NEED the semicolon when we are calling the method, just like we were doing with the other method.

This method is of type void because it doesn't return a value; the parentheses are empty because it takes no arguments. The curly braces that follows, show the beginning and end of the method. Within the braces, the variables are declared (just as they are in paint()):

int     i;
int     junk;

After this, the loop is executed which simply waist some time to give the illusion of time delay in our program.

Methods with Arguments

Usually we want to send arguments or values to a function to control what it does. In BounceFife.java, the method Sleep() has been modified to take one argument, for the duration of time for it to sleep. This can be used to better utilize the Sleep() method by controlling it to how long to sleep. The definition of the method has been changed to read:

void Sleep(int duration)
{
    ....
    ....
}

The input variable duration is used in Sleep() method to get a time duration for how long the method to delay time. Back in paint(), we see:

Sleep(ONE_SECOND);

The final variable: ONE_SECOND is used as argument to the method. It is important to know that if we use a variable identifier as an argument to a method:

Sleep(ONE_SECOND);

that the method will only get the VALUE of the variable, and it WON'T actually have access to the variable or be able to change it. In this example:

public static void main(String args[])
{
    int x;
    
    x = 5;
    System.out.println("Value of x in main() BEFORE calling DoubleIt() = " + x);
    DoubleIt(x);
    System.out.println("Value of x in main() AFTER calling DoubleIt() = " + x);
}

/* the DoubleIt() method */
void Double(int x)
{
    System.out.println("Value of x in DoubleIt() BEFORE operation = " + x);
    x = x * 2;
    System.out.println("Value of x in DoubleIt() AFTER operation = " + x);
}

The output of the program will be:

Value of x in main() BEFORE calling double() = 5
Value of x in DoubleIt() BEFORE operation = 5
Value of x in DoubleIt() AFTER operation = 10
Value of x in main() AFTER calling double() = 5

Even though both main() and DoubleIt() use variables called x, the two variables are distinct and local to the method. A method cannot change the value of a variable external to it unless if the method is global within the class.

If we need a method that takes more then one arguments, we specify it by separating each argument with a comma:

public static void main(String args[])
{
    int x, y;
    
    x = 5;
    y = 10;
    z = 15;

    TestOne(x, y);      /* pass the two argument to the method */
    TestTwo(z, y, x);   /* pass the three argument to the method */
}

/* the TestOne() method which takes two int arguments */
void Double(int x, int y)
{
    int     z;

    z = x + y;
}

/* the TestTwo() method which takes three int arguments */
void TestTwo(int a, int b, int c)
{
    /* do what ever we want in this method */
}

Methods that return a value

Often, a method returns a value to the statement that called it. In BounceSix.java, the method IsInsideTheBox() is introduced -- it takes arguments for a point via (xp, yp) and a rectangle defined by (int x, int y, int width, int height). It determines if the give point is inside the given box or not. If so it will return 1. If the point is outside the box it will return 0.

Because this method will return a value (an int in this case) it must be declared to indicate that fact. This is done as follows:

int     IsInsideTheBox(int xp, int yp, int x, int y, int width, int height)

At the end of the method, the resulting value is returned:

return (insideBox);

return is a Java keywords that returns the value in the parentheses to the method which called it. In BounceSix.java, paint() calls IsInsideTheBox().

Another way to use the return keyword in the method IsInsideTheBox() is as follows:

int IsInsideTheBox(int xp, int yp, int x, int y, int width, int height)
{
    if ((xp > x && xp < x + width) && (yp > y && yp < yp + height))
        return (1);
    else
        return (0);
}

We should note that any statement after the return statement are NEVER executed. In fact it is an error. Thus in the following example:

int BuggyMethod()
{
    int     x, y, z;
    
    x = 1;
    y = 2;
    z = 0;
    
    return (z);
    
    z = x + 1;    /* COMPILIER ERROR: this line will never execute - it is unreachable */
}

The Java compiler will give us an error message telling us that z = x + 1 is unreachable.


Back to the top of this page. Back to main Index.

 

Sample Programs -- Batch Four

BounceFour.java

/*
 *  Program:    BounceFour.java
 *  Purpose:    A simple method
 *  Author:     George Aroush
 *  Date:       1/1/1998
 *  Change Log: None
 *
 *  Full description of Program:
 *      Shows how to create a new method that take no variable and returns no nothing
 */

public class BounceFour extends java.applet.Applet
{
    final int   X_RES = 640;
    final int   Y_RES = 480;
    final int   NUM_CIRCLES = 1000;
    final int   ONE_SECOND = 10000;

    public void paint(java.awt.Graphics g)
    {
        int     x, y;
        int     xSpeed, ySpeed;
        int     width, height;
        int     i;

        x = X_RES / 2;
        y = Y_RES / 2;
        xSpeed = 6;
        ySpeed = 3;
        width = height = 10;

        i = 0;
        while (i < NUM_CIRCLES)     /* here the constant tells what the loop is counting */
        {
            g.clearRect(0, 0, X_RES, Y_RES);    /* clear the screen */

            g.drawRect(x, y, width, height);    /* draw the rectangle */

                /* move the rectangle */
            x = x + xSpeed;
            y = y + ySpeed;

                /* check for x-direction change */
            if (x < 0 || x + width > X_RES)
                xSpeed = -xSpeed;

                /* check for y-direction change */
            if (y < 0 || y + height > Y_RES)
                ySpeed = -ySpeed;

            Sleep();    /* slow things down a bit */

            i++;        /* same as: i = i + 1; */
        }
    }

    /*	
     *  void    Sleep()
     *
     *  Intended to slow things down -- a bad way to do it but OK for now
     */
    void	Sleep()
    {
        int     i;
        int     junk;

        junk = 0;
        i = 0;
        while (i < ONE_SECOND)
        {
            junk = junk + i * junk;

            i++;
        }
    }
}

BounceFour.htm

<html>
<head>
<title>BounceFour</title>
</head>
<body>
    <hr>
    <applet code=BounceFour width=640 height=480></applet>
    <hr>
</body>
</html>

BounceFive.java

/*
 *  Program:    BounceFive.java
 *  Purpose:    A method that takes an argument
 *  Author:     George Aroush
 *  Date:       1/1/1998
 *  Change Log: None
 *
 *  Full description of Program:
 *      Shows how to create a new method that take a variable and returns no nothing
 */

public class BounceFive extends java.applet.Applet
{
    final int   X_RES = 640;
    final int   Y_RES = 480;
    final int   NUM_CIRCLES = 1000;
    final int   ONE_SECOND = 10000;

    public void paint(java.awt.Graphics g)
    {
        int     x, y;
        int     xSpeed, ySpeed;
        int     width, height;
        int     i;

        x = X_RES / 2;
        y = Y_RES / 2;
        xSpeed = 6;
        ySpeed = 3;
        width = height = 10;

        i = 0;
        while (i < NUM_CIRCLES)     /* here the constant tells what the loop is counting */
        {
            g.clearRect(0, 0, X_RES, Y_RES);    /* clear the screen */

            g.drawRect(x, y, width, height);    /* draw the rectangle */

                /* move the rectangle */
            x = x + xSpeed;
            y = y + ySpeed;

                /* check for x-direction change */
            if (x < 0 || x + width > X_RES)
                xSpeed = -xSpeed;

                /* check for y-direction change */
            if (y < 0 || y + height > Y_RES)
                ySpeed = -ySpeed;

            Sleep(ONE_SECOND / 2);  /* slow things down a bit */

            i++;        /* same as: i = i + 1; */
        }
    }

    /*	
     *  void    Sleep()
     *
     *  Intended to slow things down -- a bad way to do it but OK for now
     */
    void	Sleep(int duration)
    {
        int     i;
        int     junk;

        junk = 0;
        i = 0;
        while (i < duration)
        {
            junk = junk + i * junk;

            i++;
        }
    }
}

BounceFive.htm

<html>
<head>
<title>BounceFive</title>
</head>
<body>
    <hr>
    <applet code=BounceFive width=640 height=480></applet>
    <hr>
</body>
</html>

BounceSix.java

/*
 *  Program:    BounceSix.java
 *  Purpose:    A simple method with a return value
 *  Author:     George Aroush
 *  Date:       1/1/1998
 *  Change Log: None
 *
 *  Full description of Program:
 *      Shows how to create a new method that takes multiple variable and returns an int value
 */

public class BounceSix extends java.applet.Applet
{
    final int   X_RES = 640;
    final int   Y_RES = 480;
    final int   NUM_CIRCLES = 2000;
    final int   ONE_SECOND = 10000;
    final int   BOX_X_POS = 100;
    final int   BOX_Y_POS = 100;
    final int   BOX_WIDTH = 200;
    final int   BOX_HEIGHT = 200;

    public void paint(java.awt.Graphics g)
    {
        int     x, y;
        int     xSpeed, ySpeed;
        int     width, height;
        int     i;

        x = X_RES / 2;
        y = Y_RES / 2;
        xSpeed = 2;
        ySpeed = 1;
        width = height = 20;

        i = 0;
        while (i < NUM_CIRCLES)     /* here the constant tells what the loop is counting */
        {
            g.clearRect(0, 0, X_RES, Y_RES);    /* clear the screen */

            if (IsInsideTheBox(x, y, BOX_X_POS, BOX_Y_POS, BOX_WIDTH, BOX_HEIGHT) == 1)
                g.fillOval(x, y, width, height);    /* draw the rectangle */
            else
                g.drawRect(x, y, width, height);    /* draw the rectangle */

                /* move the rectangle */
            x = x + xSpeed;
            y = y + ySpeed;

                /* check for x-direction change */
            if (x < 0 || x + width > X_RES)
                xSpeed = -xSpeed;

                /* check for y-direction change */
            if (y < 0 || y + height > Y_RES)
                ySpeed = -ySpeed;

            Sleep(ONE_SECOND * 10);  /* slow things down a bit */

            i++;        /* same as: i = i + 1; */
        }
    }


    /*	
     *  void    IsInsideTheBox()
     *
     *  Returns a value of 1 if the point (xp, yp) is inside the box given by:
     *  (x, y, width, height), if not it returns 0
     */
    int     IsInsideTheBox(int xp, int yp, int x, int y, int width, int height)
    {
        int     insideBox;

        if ((xp > x && xp < x + width) && (yp > y && yp < y + height))
            insideBox = 1;
        else
            insideBox = 0;

        return (insideBox);
    }

    /*	
     *  void    Sleep()
     *
     *  Intended to slow things down -- a bad way to do it but OK for now
     */
    void	Sleep(int duration)
    {
        int     i;
        int     junk;

        junk = 0;
        i = 0;
        while (i < duration)
        {
            junk = junk + i * junk;

            i++;
        }
    }
}

BounceSix.htm

<html>
<head>
<title>BounceSix</title>
</head>
<body>
    <hr>
    <applet code=BounceSix width=640 height=480></applet>
    <hr>
</body>
</html>

Back to the top of this page. Back to main Index.