Summary: Learn how to incorporate GUI components into a World object. In particular, learn how to add a JButton object to a World object and register an action listener on the button to control the behavior of the program.
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 figures and listings while you are reading about them.
In this module, you will learn how to incorporate GUI components into a World object. In particular, you will learn how to add a JButton object to a World object and register an action listener on the button to control the behavior of the program.
Program specifications
Write a program named Prob03 that uses the Prob03 class definition shown in Listing 2 and Ericson's media library to produce the graphic output images shown in Figure 1 and Figure 2 .
The image shown in Figure 1 is the image that appears on the screen when the program starts running.
| Initial screen output. |
|---|
![]() |
Click the button
The image shown in Figure 2 is what you should see when you click the button at the bottom of the world.
| Screen output after clicking the button. |
|---|
![]() |
Modify Ericson's World class
You must copy and modify (as necessary) the media class named World to cause your program to produce the required output with the required behavior.
Add a JButton to the World
This program adds a JButton object to the SOUTH location of the World object as shown in Figure 1 and Figure 2 and registers an action listener on the button to control the behavior of the program.
Program behavior
The program initially displays an empty white world as shown in Figure 1 . When the user clicks the button, the world's background color changes to blue, a turtle appears in the center of the World , and the student's name appears near the top of the world.
Output text
In addition to the output images described above, your program must produce the text output shown in Figure 3 on the command- line screen
| Required text output. | |
|---|---|
|
Analysis
A World object is actually a specialized use of a standard Java JFrame object. However, by default, the frame is not available to users of the World class. Therefore, in order to satisfy the requirements of this program, the World class must be modified to provide access to the frame.
Add a getFrame method
This program adds a method named getFrame to the World class. The getFrame method returns a reference to the JFrame object that is used to display the world. This makes it possible to treat World objects in much the same way that other JFrame objects are treated.
Add a button and pack the frame
The program uses the JFrame object's reference to add a JButton object to the SOUTH location of the JFrame . After adding the button, the program calls the pack method on the frame to cause the size of the frame to be automatically adjusted to accommodate both the Picture object that constitutes the background and the JButton object.
A complete listing of the modified World class is provided in Listing 10 near the end of the module
Getting access to the frame
An object of the World class contains a private instance variable named frame that contains a reference to the JFrame object. Because it is private, however, it is not available to users of the World class. The getter method shown in Listing 1 was added to the World class to provide access to the JFrame .
public JFrame getFrame(){
System.out.println("Dick Baldwin");
return frame;
}//end getFrameThe new method also displays the student's name when the method is called, producing part of the text output in Figure 3 .
No other change to is required
This is the only change to Ericson's library that is required to write this program. Everything else in the program makes use of existing library classes with no modifications.
Will explain in fragments
I will explain this program in fragments. A complete listing is shown in Listing 9 near the end of the module.
The driver class
The driver class for this program is named Prob03 . The definition of the driver class is shown in its entirety in Listing 2 .
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;
public class Prob03{
public static void main(String[] args){
new Prob03Runner().run();
}//end main method
}//end class Prob03The driver class simply instantiates a new object of a class named Prob03Runner and calls a method named run on that object.
Beginning of the Prob03Runner class
The beginning of the Prob03Runner class and the constructor for the class is shown in Listing 3 .
class Prob03Runner{
public Prob03Runner(){
System.out.println("Dick Baldwin");
}//end constructorAs you can see, the constructor simply displays the student's name, providing some of the text output shown in Figure 3 .
Beginning of the run method
The beginning of the run method is shown in Listing 4 . This is where things start to get interesting.
public void run(){
//This reference must be final because it is
// referenced from within an anonymous class
// definition.
final World world = new World(200,300);
//Get a reference to the JFrame object that is used
// to display the World.
JFrame frame = world.getFrame();
//Instantiate a new JButton object and add it to the
// SOUTH location in the JFrame object.
JButton button = new JButton(
"Click to make a turtle.");
frame.getContentPane().add(button,BorderLayout.SOUTH);
frame.pack();//VERY IMPORTANTA new World object
Listing 4 begins by instantiating a new object of the World class with a size of 200x300 pixels. The reference to the object is saved in a final variable named world .
A final reference variable
As the comment indicates, the variable must be final because it is referenced from within an anonymous class definition. I won't take the time to explain that here. I will simply refer you to my website where I have published several tutorial modules on anonymous classes.
The size of the world...
The purpose of specifying the size of the world when it is instantiated is to implicitly specify the size of the Picture object that forms the background for the world.
The size of the picture actually matches the specified dimensions. Therefore the actual size of the world is a little larger than the specified dimensions due to the borders that surround the picture.
Get a reference to the frame
After the World object is instantiated, the new getFrame method is called on the world's reference in order to get and save a reference to the frame.
A new JButton object
Then a new JButton object is instantiated. The reference to the JButton object is saved in the variable named button .
Add the button to the frame and pack it
Then the button is added to the SOUTH location in the frame and the pack method is called on the frame. Calling the pack method causes the size of the frame, (and hence the size of the world) to be adjusted so as to accommodate the picture in the CENTER of the frame and the button at the bottom (SOUTH) of the frame.
The final size of the world
After the button is added and the world is packed, the overall height of the world is quite a bit larger than the original dimensions. I measured it and found it to be about 209x361 pixels including borders.
The expansion in height is necessary to make room for the button. However, as you can see in Figure 3 , the size of the picture remains at 200x300 pixels.
Register an action listener on the button
I elected to use an anonymous class to register an action listener on the button. The purpose of the listener is to produce the desired behavior when the button is clicked.
Note, however, that there are other ways to register an action listener on the button and the student is not required to use an anonymous class for that purpose.
Beginning of the anonymous class
The definition of the anonymous listener class and the instantiation of the listener object begins in Listing 5 .
button.addActionListener(new ActionListener()
{//Begin the class definition
public void actionPerformed(ActionEvent e){
Picture picture = world.getPicture();
System.out.println(picture);Unfamiliar with anonymous classes?
If you are unfamiliar with anonymous classes and action listeners, I will simply refer you to my website where I have published several tutorial modules on the topic. I have also published modules on the topic in this collection.
In a nutshell...
In a nutshell, however, the method named actionPerformed , which begins in Listing 5 , will be executed each time the user clicks the button in Figure 1 .
Behavior of the actionPerformed method
The code in Listing 5 gets and saves a reference to the Picture object that forms the background in the world object. Then it passes a copy of that reference to the println method, producing the third line of output text shown in Figure 3 .
Set the background picture to blue
Listing 6 calls the method named setAllPixelsToAColor on the Picture object passing the color BLUE as a parameter.
picture.setAllPixelsToAColor(Color.BLUE);As you might expect, this causes the background of the world to turn from white to blue as shown in Figure 2 .
Display the student's name on the picture
Listing 7 calls the addMessage method on the picture to add the student's name near the upper-left corner of the world. (See Figure 2 .)
picture.addMessage("Dick Baldwin",10,20);Finally, Listing 8 instantiates a new Turtle object in the default color, with the default heading (north) , located in the default position, which is the center of the picture that constitutes the background image for the world.
Turtle turtle = new Turtle(world);
}//end actionPerformed
}//end class definition
);//end addActionListener
}//end run
//----------------------------------------------------//
}//end class Prob03RunnerMultiple clicks
If you click the button more than once, you will instantiate a new Turtle object and produce a line of output text on the command line screen with each click. The turtles will all be in the same location but they will cycle through four different color schemes.
Note that adding the turtle to the world causes the world to be repainted, eliminating the requirement to purposely repaint the world.
End the run method
Finally, Listing 8 signals the end of the run method, causing the run method to terminate and return control to the main method in Listing 2 . The main method terminates causing the program to terminate.
I encourage you to copy the code from Listing 9 and Listing 10 . Compile the code 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.
In this module, you learned how to incorporate GUI components into a World object. In particular, you learned how to add a JButton object to a World object and register an action listener on the button to control the behavior of the program.
In the next module, you will learn how to modify the SimplePicture class to make it possible to control the color of the text that is placed on the image in a Picture object. Then you will place a turtle object in a world and perform a series of maneuvers causing the turtle to draw a square spiral.
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 copied my modules from cnx.org, converted them to Kindle books, and placed them for sale on Amazon.com showing me as the author. I neither receive compensation for those sales nor do I know who does receive compensation. If you purchase such a book, please be aware that it is a copy of a module that is freely available on cnx.org and that it was made and published without my prior knowledge.
Affiliation : I am a professor of Computer Information Technology at Austin Community College in Austin, TX.
Complete listings of the programs discussed in this module are provided below.
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;
public class Prob03{
public static void main(String[] args){
new Prob03Runner().run();
}//end main method
}//end class Prob03
//======================================================//
class Prob03Runner{
public Prob03Runner(){
System.out.println("Dick Baldwin");
}//end constructor
//----------------------------------------------------//
public void run(){
//This reference must be final because it is
// referenced from within an anonymous class
// definition.
final World world = new World(200,300);
//Get a reference to the JFrame object that is used
// to display the World.
JFrame frame = world.getFrame();
//Instantiate a new JButton object and add it to the
// SOUTH location in the JFrame object.
JButton button = new JButton(
"Click to make a turtle.");
frame.getContentPane().add(button,BorderLayout.SOUTH);
frame.pack();//VERY IMPORTANT
//Use an anonymous class to register an action
// listener on the button. Note that the student is
// not required to use an anonymous class.
button.addActionListener(new ActionListener()
{//Begin the class definition
public void actionPerformed(ActionEvent e){
Picture picture = world.getPicture();
System.out.println(picture);
//Set picture background to blue.
picture.setAllPixelsToAColor(Color.BLUE);
//Display the student's name on the picture.
picture.addMessage(
"Dick Baldwin",10,20);
//Add a turtle to the world. This causes the
// world to be repainted.
Turtle turtle = new Turtle(world);
}//end actionPerformed
}//end class definition
);//end addActionListener
}//end run
//----------------------------------------------------//
}//end class Prob03Runnerimport javax.swing.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Observer;
import java.awt.*;
/*12/23/08 Modified the World class. Added a method named
*getFrame that returns a reference to the JFrame object
*in which the turtles are displayed.
*/
/**
* Class to represent a 2d world that can hold turtles and
* display them
*
* Copyright Georgia Institute of Technology 2004
* @author Barb Ericson ericson@cc.gatech.edu
*/
public class World extends JComponent implements ModelDisplay
{
////////////////// fields ///////////////////////
/** should automatically repaint when model changed */
private boolean autoRepaint = true;
/** the background color for the world */
private Color background = Color.white;
/** the width of the world */
private int width = 640;
/** the height of the world */
private int height = 480;
/** the list of turtles in the world */
private List<Turtle> turtleList = new ArrayList<Turtle>();
/** the JFrame to show this world in */
private JFrame frame = new JFrame("World");
/** background picture */
private Picture picture = null;
////////////////// the constructors ///////////////
/**
* Constructor that takes no arguments
*/
public World()
{
// set up the world and make it visible
initWorld(true);
}
/**
* Constructor that takes a boolean to
* say if this world should be visible
* or not
* @param visibleFlag if true will be visible
* else if false will not be visible
*/
public World(boolean visibleFlag)
{
initWorld(visibleFlag);
}
/**
* Constructor that takes a width and height for this
* world
* @param w the width for the world
* @param h the height for the world
*/
public World(int w, int h)
{
width = w;
height = h;
// set up the world and make it visible
initWorld(true);
}
///////////////// methods ///////////////////////////
/**
*Method to return a reference to the JFrame.
*/
public JFrame getFrame(){
System.out.println("Dick Baldwin");
return frame;
}//end getFrame
/**
* Method to initialize the world
* @param visibleFlag the flag to make the world
* visible or not
*/
private void initWorld(boolean visibleFlag)
{
// set the preferred size
this.setPreferredSize(new Dimension(width,height));
// create the background picture
picture = new Picture(width,height);
// add this panel to the frame
frame.getContentPane().add(this);
// pack the frame
frame.pack();
// show this world
frame.setVisible(visibleFlag);
}
/**
* Method to get the graphics context for drawing on
* @return the graphics context of the background picture
*/
public Graphics getGraphics() { return picture.getGraphics(); }
/**
* Method to clear the background picture
*/
public void clearBackground() { picture = new Picture(width,height); }
/**
* Method to get the background picture
* @return the background picture
*/
public Picture getPicture() { return picture; }
/**
* Method to set the background picture
* @param pict the background picture to use
*/
public void setPicture(Picture pict) { picture = pict; }
/**
* Method to paint this component
* @param g the graphics context
*/
public synchronized void paintComponent(Graphics g)
{
Turtle turtle = null;
// draw the background image
g.drawImage(picture.getImage(),0,0,null);
// loop drawing each turtle on the background image
Iterator iterator = turtleList.iterator();
while (iterator.hasNext())
{
turtle = (Turtle) iterator.next();
turtle.paintComponent(g);
}
}
/**
* Metod to get the last turtle in this world
* @return the last turtle added to this world
*/
public Turtle getLastTurtle()
{
return (Turtle) turtleList.get(turtleList.size() - 1);
}
/**
* Method to add a model to this model displayer
* @param model the model object to add
*/
public void addModel(Object model)
{
turtleList.add((Turtle) model);
if (autoRepaint)
repaint();
}
/**
* Method to check if this world contains the passed
* turtle
* @return true if there else false
*/
public boolean containsTurtle(Turtle turtle)
{
return (turtleList.contains(turtle));
}
/**
* Method to remove the passed object from the world
* @param model the model object to remove
*/
public void remove(Object model)
{
turtleList.remove(model);
}
/**
* Method to get the width in pixels
* @return the width in pixels
*/
public int getWidth() { return width; }
/**
* Method to get the height in pixels
* @return the height in pixels
*/
public int getHeight() { return height; }
/**
* Method that allows the model to notify the display
*/
public void modelChanged()
{
if (autoRepaint)
repaint();
}
/**
* Method to set the automatically repaint flag
* @param value if true will auto repaint
*/
public void setAutoRepaint(boolean value) { autoRepaint = value; }
/**
* Method to hide the frame
*/
// public void hide()
// {
// frame.setVisible(false);
// }
/**
* Method to show the frame
*/
// public void show()
// {
// frame.setVisible(true);
// }
/**
* Method to set the visibility of the world
* @param value a boolean value to say if should show or hide
*/
public void setVisible(boolean value)
{
frame.setVisible(value);
}
/**
* Method to get the list of turtles in the world
* @return a list of turtles in the world
*/
public List getTurtleList()
{ return turtleList;}
/**
* Method to get an iterator on the list of turtles
* @return an iterator for the list of turtles
*/
public Iterator getTurtleIterator()
{ return turtleList.iterator();}
/**
* Method that returns information about this world
* in the form of a string
* @return a string of information about this world
*/
public String toString()
{
return "A " + getWidth() + " by " + getHeight() +
" world with " + turtleList.size() + " turtles in it.";
}
} // end of World class-end-