Summary: Learn how to create and manipulate Turtle objects and Picture objects in a World object using the Guzdial-Ericson multimedia library.
This module is one of a series of modules designed to teach you about Object-Oriented Programming (OOP) using Java.
The program described in this module requires the use of the Guzdial-Ericson multimedia class library. You will find download, installation, and usage instructions for the library at Java OOP: The Guzdial-Ericson Multimedia Class Library .
I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the images and listings while you are reading about them.
In this module, I will explain a program that uses Java and Ericson's media library to (see Image 1 ) :
Stated in more detail, the program will:
Program output
Image 1 shows the graphic screen output produced by this program.
| Image 1: Graphic screen output. |
|---|
![]() |
Image 2 shows the text output produced by the program on the command line screen.
| Image 2: Command-line output. |
|---|
|
Output produced by the system
Image 2 not only shows the output produced by the program. It also shows information produced by the Java compiler and the Java virtual machine as a result of executing the following commands at runtime:
javac -version
java -versionWill explain in fragments
I will explain this program in fragments. A complete listing of the program is provided in Listing 9 near the end of the module.
I will begin with the driver class named Prob01 , which is shown in its entirety in Listing 1 .
| Listing 1: The driver class. |
|---|
|
The import directive
Note the import directive at the very beginning of Listing 1 . This is a directive to the compiler and the virtual machine notifying them that the class named Color can be found in the package named java.awt .
What is a package?
Boiled down to its simplest description, a package is nothing more than the specification of a particular folder on the disk relative to a standard root folder. (Think of it as a disk-path specification with the periods representing \ characters on a Windows machine and representing / characters on a Unix machine.)
The public class named Prob01
Every Java application (not true for Java applets) must include the definition of a class that contains the definition of a method named main with a method signature having the syntax shown in Listing 1 .
The name of the class/application
The name of the class containing the main method is also the name of the application insofar as being able to compile and execute the application is concerned. In this case, the name of the class, and hence the name of the application is Prob01 .
Source code file name
The name of the source code file containing this class must match the name of the class. In this case, the source code file must be named Prob01.java . (Note the .java extension.)
Compiling the application
In its simplest form, this application can be compiled by executing the following command at the command prompt:
javac Prob01.java Note however that it is often necessary to specify the path to various library files on the command line when compiling the application. In that case, the simplest form given above is not sufficient.
Compiler output file names
When the application is successfully compiled, it will produce one or more output files with an extension of .class . In this case, one of those files will be named Prob01.class .
Execution of the application
The execution of C and C++ programs begins and ends in the main function. The execution of Java applications begin and end in the method named main .
Once again, in its simplest form, this application can be executed by entering the following command at the command prompt:
java Prob01 Again, it is often necessary to specify the path to various library files on the command line when executing the application. In that case, the simplest form is not sufficient.
Compilation and execution on my machine
This application can be compiled and executed on my machine by entering the two commands shown in Image 3 at the command prompt. (Note that artificial line breaks were inserted into Image 3 to force the long commands to fit this narrow format.)
| Image 3: Commands to compile and execute the application. |
|---|
|
The compiler and the virtual machine
The javac portion of the first command causes the Java compiler to run.
The java portion of the second command causes the Java virtual machine to run.
The input files
The Prob01.java and Prob01 at the ends of the two commands specify the files being operated on by the compiler and the virtual machine respectively.
A classpath
In both cases, the -cp indicates that a classpath follows.
A classpath consists of one or more path specifications separated by semicolon characters.
The purpose of the classpath is to tell the compiler and the virtual machine where to look for previously compiled class files that the application needs in order to successfully compile and execute.
The current folder
The period ahead of the semicolon says to search the current folder first.
The path to the Ericson library
The material following the semicolon is the absolute path to the folder containing the class files that make up Ericson's library on my machine. The location of that folder will probably be different on your machine.
The main method
Now that we have the preliminaries out of the way, let's go back and examine the body of the main method in Listing 1 .
The first statement in the body of the main method in Listing 1 instantiates a new object of the class named Prob01Runner .
The statement saves a reference to that object in a reference variable named obj . Note that the type of the variable is the same as the name of the class in this case. In general, the type of the variable must be:
Accessing the object
You must save a reference to an object in order to gain access to the object later. In this case, the reference is stored in the variable named obj .
Call the method named run
The second statement in the body of the main method in Listing 1 uses that reference to call the method named run encapsulated in the object. As you will see later, most of the work in this application is performed in the method named run .
Get and display information about the object
When the run method returns control to the main method, the last three statements in the body of the main method in Listing 1 use the object's reference to call the following three methods belonging to the object:
Accessor methods
These three methods are of a type that is commonly referred to as accessor methods . They access and return values encapsulated inside an object. In most cases, (using good programming practice) they return copies of the values. This protects the encapsulated values from being corrupted by code outside the object.
The method named println
In each case in Listing 1 , the value returned by the method is passed to a method named println . This is a method belonging to a standard system object that represents the standard output device (usually the command-line screen) . The purpose of the println method is to display material on the command-line screen.
System.out.println...
Without going into detail about how this works, you should simply memorize the syntax of the last three statements in the body of the main method in Listing 1 . I explain the concepts involved in great detail on my website. Go to Google and search for the following keywords:
baldwin java "class variable named out" This code (System.out.println...) provides the mechanism by which you can display material on the command line screen in a running Java application. The last three statements in the main method in Listing 1 produced the last three lines of text in Image 2 .
(Note that only the last four lines of text in Image 2 were produced by the program. Everything above that was produced by the system during the compilation and initial execution of the application.)
What do you know so far?
So far, you know the following to be true:
The public modifier
Java uses four access modifiers to specify the accessibility of various classes and members in a Java application:
Rather than trying to explain all four at this time, I will explain public here and explain the other three when we encounter them in code.
The public modifier is the easiest of the four to explain. As the name implies, it is analogous to a public telephone. Any code that can find a class or class member with a public modifier can access and use it. In this case, any code that can find the class definition for the class named Prob01 can instantiate an object of that class.
The class named Prob01Runner
There's not a lot more that we can say about the driver class named Prob01 , so it's time to analyze the class named Prob01Runner . We need to figure out what it is about that class that causes the program output to match the material shown in Image 1 and Image 2 .
Beginning of the class named Prob01Runner
The definition of the class named Prob01Runner begins in Listing 2 .
| Listing 2: Beginning of the class named Prob01Runner. |
|---|
|
No access modifier
Note that this class definition does not have an access modifier. This puts it in package-private access category. A class with package-private access can be accessed by code that is stored in the same package and cannot be accessed by code stored in other packages.
Three private variables
The last three statements in Listing 2 declare three private variables. Because these variables are declared private, they can only be accessed by code contained in methods defined inside the class.
(They are also accessible by code contained in methods defined in classes defined inside the class, but that is beyond the scope of this module.)
Three private instance variables
These variables are also instance variables as opposed to class variables . (We will discuss class variables in a future module.)
Because they are instance variables, they belong to an object instantiated from the class. (An object is an instance of a class.) Even if the variables were public, they could only be accessed by first gaining access to the object to which they belong.
Multiple instances of the class
If you instantiate multiple objects of this same class (create multiple instances which you often do) , each object will encapsulate the same set of the three private instance variables shown in Listing 2 . Instance variables have the same name but may have different values in the different objects.
Three private instance reference variables
The three variables declared in Listing 2 are also reference variables (as opposed to primitive variables) . This means that they are capable of storing references to objects as opposed to simply being able to store primitive values of the following eight types:
Primitive variables can only store primitive values of the types in the above list.
Classes, classes, and more classes
A Java application consists almost exclusively of objects. Objects are instances of classes. Therefore, class definitions must exist before objects can exist.
The true power of Java
The Java programming language is small and compact. The true power of Java lies in its libraries of predefined classes.
The Java standard edition development kit and runtime engine available from Sun contains a library consisting of thousands of predefined classes. Other class libraries containing thousands of classes are available from sun in the enterprise edition and the micro edition.
Non-standard class libraries
In some cases, you or your company may create your own class libraries and/or obtain class libraries from other sources such as the Ericson class library that we are using in this module.
Custom class definitions
In almost all cases, you will need to define a few new classes for new applications that you write. We will define two new classes for this application. The remainder of the classes that we use will come either from Sun's standard library or Ericson's library.
Objects of the World class and the Turtle class
Ericson's class library contains a class named World and another class named Turtle . The code in Listing 2 instantiates one object of the World class and populates that world with two objects of the Turtle class.
Every class has a constructor
Every class definition has one or more method-like members called constructors. (If you don't define a constructor when you define a class, a default constructor will be automatically defined for your class.)
The name of the constructor must always be the same as the name of the class. Like a method, a constructor may or may not take arguments. If there are two or more (overloaded) constructors, they must have different argument lists.
Instantiating an object of a class
To instantiate an object of a class, you apply the new operator (see Listing 2 ) to the class' constructor, passing parameters that satisfy the required arguments for the constructor.
Return a reference to the object
Once the object has been instantiated, the constructor returns a reference to the new object.
A new World object
For example, the first statement in Listing 2 applies the new operator to Ericson's World class constructor passing two integer values as parameters. This causes a new World object to be instantiated.
A reference is returned
A reference to the new World object is returned and stored in the reference variable named mars .
Once the reference is stored in the reference variable, it can be used to access the World object later.
Constructors for the World class
Image 4 s shows the constructors that are available for Ericson's World class. (See javadocs for the Ericson library.)
| Image 4: Constructors for the World class. |
|---|
![]() |
A new World object
The third constructor in Image 4 was used to construct a World object in Listing 2 with a width of 300 pixels and a height of 274 pixels. As explained earlier, this object's reference was saved in the variable named mars .
Two new Turtle objects
The last two statements in Listing 2 instantiate two objects of the Turtle class and use them to populate the World object whose reference is stored in the variable named mars .
More complicated than before
This is a little more complicated than the instantiation of the World object. Ericson's javadocs indicate that the Turtle class provides the four constructors shown in Image 5 .
| Image 5: Constructors for the Turtle class. |
|---|
![]() |
A World object as a parameter
If you dig deep enough, and if you study Ericson's textbook, you can determine that the third constructor in Image 5 will accept a reference to a World object as a parameter. This is the constructor that was used in the last two statements in Listing 2 .
The World class implements the ModelDisplay interface. Therefore, an object of the World class can be treated as it is type ModelDisplay. I explain the relationship between classes and interfaces in detail on my website.
Displayed in the center of the world
When the two Turtle objects instantiated in Listing 2 come into existence, they will be displayed in the center of the World object referred to by the contents of the variable named mars . However, that happens so quickly that you probably won't see it when you run this program.
Eliminating the run method call
If you were to eliminate the call to the run method in Listing 1 , you would see a world with a white background and a single turtle positioned in the center of the world facing north. There would actually be two turtles there, but they would be in exactly the same location so only the one closest to you would be visible.
The constructor for the Prob01Runner class
That's probably enough discussion of the three statements in Listing 2 . The constructor for the class named Prob01Runner is shown in its entirety in Listing 3 .
| Listing 3: The constructor for the Prob01Runner class. |
|---|
|
The purpose of constructors
The primary purpose for which constructors exist is to assist in the initialization of the variables belonging to the object being constructed. However, it is possible to directly initialize the variables as shown in Listing 2 .
Initialization of variables
When an object comes into existence, the variables belonging to that object will have been initialized by any direct initializers like those shown in Listing 2 as well any initialization produced by code written into the constructor.
Default initialization
If a variable (exclusive of local variables inside of methods) is not initialized in one of those two ways, it will receive a default initialization value. The default values are:
Non-initialization code in constructors
Although it is usually not good programming practice to do so, there is no technical reason that you can't write code into the constructor that has nothing to do with variable initialization. Such code will be executed when the object is instantiated.
An object counter
For example, you might need to keep track of the number of objects that are instantiated from a particular class, such as the total number of asteroid objects in a game program for example You could write the code to do the counting in the constructor.
Display my name
The code in the constructor in Listing 3 simply causes my name to be displayed on the command-line screen when the object is instantiated. That is how my name appears ahead of the other lines of output text in Image 2 . My name is displayed when the object is instantiated. The remaining three lines of text in Image 2 are displayed later by manipulating the object.
Three accessor methods
Listing 4 defines three accessor methods that are used to access and return copies of the contents of the private instance variables named joe , sue , and mars .
| Listing 4: Three accessor methods. |
|---|
|
Good OOP practice
Good object-oriented programming practice says that most of the instance variables encapsulated in an object should be declared private. If there is a need to make the contents of those variables available outside the object, that should be accomplished by defining public accessor methods. (Accessor methods are often referred to as getter methods because the name of the accessor method often includes the word "get".)
Setter methods
If there is a need for code outside the object to store information in the object's private instance variables, this should be accomplished by writing public setter methods. Code in the setter methods can filter incoming data to make certain that the state of the object doesn't become corrupt as a result of outside influences.
Pass and return by value
Everything in Java is passed and returned by value , not by reference.
Each of the accessor methods shown in Listing 4 returns a copy of the reference belonging to either a Turtle object or a World object.
Pass to the println method
As you saw earlier, each of the three references is passed to the println method in Listing 1 causing information about the objects to be displayed on the command-line screen.
The toString method
Although it isn't obvious in Listing 1 , the code in the println method calls a method named toString on the incoming object reference and displays the string value returned by that method. I discuss this in detail on my website. Go to Google and search for the following:
baldwin java "the toString method"An overridden method
The toString method is overridden (not overloaded) in the World and Turtle classes so as to return a string value describing the object.
The Ericson javadocs
Normally, the javadocs would tell you what information is contained in that string, but that is not the case in Ericson's javadocs. You would have to get into her source code, (which is readily available), to get that information. However, you can see the information that is contained in the string values for the two different types of objects in the last three lines of text in Image 2 .
The beginning of the run method
This is where thing start to get really interesting. Listing 5 shows the beginning of the public method named run .
| Listing 5: The beginning of the run method. |
|---|
|
Recall that the code in the main method in Listing 1 calls the run method on the object immediately after it is instantiated.
A turtle on a white background
I told you earlier that if you were to eliminate the call to the run method, you would see a turtle at the center of the world with a white background.
The background is a Picture object
The background of a World object consists of an object of Ericson's Picture class. (A Picture object is encapsulated in the World object.)
By default, the Picture object encapsulated in a World object is all white and is exactly the right size and shape to completely fill the area inside the world's border (see Image 1 ).
Can be replaced
As you will see shortly, we can replace the default Picture object with a new Picture object of our own choosing.
What if it doesn't fit?
If the new Picture object isn't large enough to completely fill the area inside the borders of the World object, it will be placed in the upper-left corner of the World object and the remainder of the World object will be a light gray color.
If the Picture object is too large, an upper-left rectangular portion of the Picture object, sufficient to fill the World object, will be displayed. The remainder of the Picture object will not be visible even if you manually resize the World object to make it larger.
Constructors for the Picture class
Image 6 shows the javadocs for the constructors for Ericson's Picture class.
| Image 6: Constructors for the Picture class. |
|---|
![]() |
Replace the default picture object
The right-hand portion of the last statement in Listing 5 uses the last constructor in Image 6 to instantiate a new Picture object that encapsulates the image contained in the image file named Prob01.jpg .
(Click here to download a copy of the file named Prob01.jpg.)
What about the size of the Picture object?
I was careful to use an image that was a little wider than and exactly as tall as the dimensions of my World object (300 x 274) . Therefore, the image completely filled the world as shown in Image 1 .
Pass the reference to a setter method
The reference belonging to the new Picture object was passed to the setPicture method of the World object (a setter method) . This caused the new picture containing the penguin to replace the default all-white picture that forms the background for the World object. (See Image 1 .)
A subclass of the SimplePicture class
Ericson's Picture class is a subclass of (extends) the class named SimplePicture . Therefore, an object of the Picture class encapsulates all of the methods defined in the Picture class in addition to all of the methods defined in the SimplePicture class.
A subclass of the Object class
Further, the SimplePicture class is a subclass of (extends) the Object class. Therefore, an object of the Picture class also encapsulates all of the methods defined in the Object class.
The AddMessage method
One of the methods defined in the SimplePicture class and inherited into the Picture class is named AddMessage .
The addMessage method requires three parameters:
The method will draw the string as text characters onto the image at the location specified by the two coordinate values.
(The origin of the coordinate system is the upper-left corner of the image with positive horizontal values going to the right and positive vertical values going down.)
Add text to the image
The code in Listing 6 uses two levels of indirection to add my name as a message to the picture that forms the background of the world as shown in Image 1 .
| Listing 6: Add text to the image. |
|---|
|
Get and access the World object
To begin with, Listing 6 goes to the variable named mars to get a reference to the World object. This reference is used to access the World object.
Access the Picture object via a getter method
Then the code in Listing 6 calls the getter method named getPicture to get access to the Picture object encapsulated in the World object.
Call the addMessage method
Having gained access to the Picture object, Listing 6 calls the addMessage method on that object passing my name as a String object along with a pair of coordinate values that specify a location near the upper-left corner of the image. The result is that my name appears in the world as shown in Image 1 .
Methods encapsulated in the Turtle object
The Turtle class extends the SimpleTurtle class, which in turn extends the Object class. Therefore, an object of the Turtle class encapsulates all of the methods defined in all three classes.
Manipulate the turtle referred to by the variable named joe
A Turtle object encapsulates many methods that can be used to manipulate the turtle in a variety of different ways. This is illustrated by the series of statements in Listing 7 .
| Listing 7: Manipulate the turtle named joe. |
|---|
|
Initial (default) state of a Turtle object
When a new Turtle object is instantiated and added to a World object (using the constructor shown in Listing 2 ) , it doesn't have a name property. (Actually, its name is probably null.)
The turtle initially appears in the center of the world, facing north with a default color.
Every Turtle object has a pen attached to its belly that can draw a line with a default width of one pixel in a default color when the turtle moves.
The pen can be raised so that it won't draw a line or lowered so that it will draw a line. Initially it is down and will draw a line.
Set the name property to "joe"
Listing 7 begins by setting the name property of one of the turtles to the string value "joe."
(Note that this is completely independent of the fact that a reference to this turtle is stored in a variable named joe . The name property could have been set to "Tom", "Dick", "Harry", or any other string value. It is the value of the name property and not the name of the variable that determines the text output shown in Image 2 .)
Set the turtle's body and shell color
Listing 7 continues by calling two setter methods on the turtle object to set the body color (head and feet) to red and the color of the shell to blue. You can see the effect of this in Image 1 .
Set the pen color and width
Then Listing 7 calls two setter methods that set the turtle's pen color to yellow and the pen width to three pixels. You can also see the result of this in Image 1 .
Make the turtle move forward
After that, Listing 7 calls the forward method (with no parameters) to cause the turtle to move forward by a default distance of 100 pixels.
Recall that the turtle initially faces north. In this case, the forward method causes the turtle to move from the center of the world to a location that is 100 pixels due north of the center of the world, drawing a wide yellow line along the way.
Turn counter clockwise
Then Listing 7 calls the turn method causing the turtle to rotate its body by 135 degrees counter-clockwise. (A positive parameter causes a clockwise rotation and a negative parameter causes a counter clockwise rotation.)
Change the pen color and move forward again
Finally Listing 7 calls methods to change the pen color to blue and to cause the turtle to move forward by 150 pixels.
The final location
After making the turn, the turtle is facing southwest. Therefore, the forward movement causes a diagonal blue line to be drawn from the position at the top of the yellow line down toward the southwest. As you can see in Image 1 , the turtle comes to rest at the end of that line.
A few words about color
I have published extensively on the concept of color in Java on my website. The best way to find that information is probably to go to Google and search for the keywords:
baldwin java colorGoogle is also probably your best bet for finding information on other topics that I have published on my website. For example, if you go to Google Images and search for the following keywords, you will find a lot of the work that I have published using Ericson's media library.
richard baldwin java ericsonManipulate the turtle named sue
Listing 8 calls several methods on the object whose reference is stored in the variable named sue .
| Listing 8: Manipulate the turtle named sue. |
|---|
|
The end result
These method calls result in the turtle facing north in the lower right corner of the window, having drawn the broken red line shown in Image 1 in getting there.
The moveTo method
Listing 8 calls the moveTo method to cause the turtle to move to a new location on the basis of coordinate values instead of on the basis of a distance value.
Pen control
Listing 8 also calls the setPenDown method twice passing false and then true as the parameter to first raise and then lower the pen. This produced the gap in the red line shown in Image 1 .
The end of the program
Listing 8 also signals the end of the method named run and the end of the class named Prob01Runner . As such, Listing 8 signals the end of the program.
II encourage you to copy the code from Listing 9 , compile it and execute it. Experiment with the code, making changes, and observing the results of your changes. Make certain that you can explain why your changes behave as they do.
II explained a program that uses Java and Ericson's media library to:
Stated in more detail, the program:
In the next module, I will teach you how to invert images and how to display images using Ericson's PictureExplorer object.
This section contains a variety of miscellaneous information.
Financial : Although the Connexions site makes it possible for you to download a PDF file for this module at no charge, and also makes it possible for you to purchase a pre-printed version of the PDF file, you should be aware that some of the HTML elements in this module may not translate well into PDF.
I also want you to know that, I receive no financial compensation from the Connexions website even if you purchase the PDF version of the module.
In the past, unknown individuals have misappropriated copies of my modules from cnx.org, converted them to Kindle books, and placed them for sale on Amazon.com showing me as the author. I receive no compensation for those sales and don't know who does receive compensation. If you purchase such a book, please be aware that it is a bootleg copy of a module that is freely available on cnx.org.
Affiliation : I am a professor of Computer Information Technology at Austin Community College in Austin, TX.
A complete listing of the program discussed in this module is shown in Listing 9 below.
| Listing 9: Source code for Prob01. |
|---|
|
-end-