The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Learning the Java Language
Lesson: Object-Oriented Programming Concepts

How Do These Concepts Translate into Code?

Now that you have a conceptual understanding of object-oriented programming let's look at how these concepts get translated into code. The following figure is a snapshot of the graphical user interface (GUI) presented by an example named ClickMeApp, which features a custom GUI component named ClickMe. A spot appears when you click the mouse inside the ClickMe component's area.

The GUI of the ClickMeApp application.

The ClickMeApp example is not large, but if you don't have much experience with programming, you might find the code daunting. We don't expect you to understand everything in this example right away, and this section won't explain every detail. The intent is to expose you to some source code and to associate it with the concepts and terminology you just learned. You will learn more details in later chapters.

Compiling and Running the Example

The ClickMeApp example has three source files: ClickMeApp.java (in a .java source file), ClickMe.java (in a .java source file), and Spot.java (in a .java source file). These source files contain the code for three classes named ClickMeApp, ClickMe, and Spot. In addition to these classes, the example uses some classes provided by the Java platform.

You can compile the ClickMeApp.java, ClickMe.java, and Spot.java files by invoking the Java compiler (javac) on ClickMeApp.java. If you're having problems compiling this example, see [PENDING: link to compiler troubleshooting will go here.]

You can run the ClickMeApp example as an application, using either Java Web Start or the java command. To run a pre-compiled version with Java Web Start, direct your browser to this URL:

http://java.sun.com/docs/books/tutorialJWS/java/concepts/ex5/ClickMeApp.jnlp (outside of the tutorial)

If you prefer to run your own copy, you can use the command java ClickMeApp. If you're having problems running this example, see [PENDING: link to execution troubleshooting will go here.]


Note: ClickMeApp depends on API introduced in J2SE 5.0. It will not run or compile under earlier versions of the JDK and runtime.

Objects in the Example

Many objects play a part in the ClickMeApp example. The most obvious ones are the ones with an onscreen representation: the window containing the GUI, the label describing what the user should do, the custom component that paints the initially empty rectangle, and the spot that's eventually painted by that custom component.

These objects are created when the user launches the application. The application's main method creates an object to represent the entire application, and that object creates others to represent the window, label, and custom component.

The object representing the custom component in turn creates an object to represent the spot on the screen. Every time you click the mouse in the custom component, the component moves the spot by changing the spot object's x,y location and repainting itself. The spot object does not display itself; the custom component paints a circle based on information contained within the spot object.

Other, nonvisible objects also play a part in the application. Three objects represent the three colors used in the custom component (black, white, and olive green), an event object represents the user action of clicking the mouse, and so on.

Classes in the Example

As you may have guessed, the object that represents the application is an instance of the ClickMeApp class, the object that represents the custom component is an instance of ClickMe, and the spot is represented by an instance of Spot.

Because the object that represents the spot on the screen is very simple, let's look at its code. The Spot class declares three instance variables: size contains the spot's radius, x contains the spot's current horizontal location, and y contains the spot's current vertical location. It also declares two methods and a constructor — a subroutine used to initialize new objects created from the class.

public class Spot {
    //instance variables
    public int x, y;
    private int size;
    
    //constructor
    public Spot() {
        x = -1;
        y = -1;
        size = 1;
    }

    //methods for access to the size instance variable    
    public void setSize(int newSize) {
        if (newSize >= 0) {
            size = newSize;
        }
    } 
    public int getSize() {
        return size;
    }
}
You can recognize a constructor because it has the same name as the class. The Spot constructor initializes all three of the object's variables. The x and y variables are set to -1, indicating that the spot is not onscreen when the application starts up. The size variable is set to a reasonable value, in this case 1.

The setSize and getSize methods provide a way for other objects to read and change the value of the size instance variable, without giving other objects access to the actual variable.

The application's ClickMe object uses a Spot object to track whether to paint a spot, and where. Here's the code from the ClickMe class that declares and creates the Spot object:

private Spot spot = null;
...
spot = new Spot();
The first line shown declares a variable named spot with a data type of Spot; it initializes the variable's value to null. The keyword null is used to specify an undefined value for variables that refer to objects. The next line shown creates the object. The new keyword allocates memory space for the object. Spot() calls the constructor you saw previously. In the next figure, the Spot class is on the left, and a newly initialized instance of Spot is on the right.

The figure on the left is a representation of the Spot class. The figure on the right is a Spot object just after its creation.

Messages in the Example

As you know, object A can use a message to request that object B do something, and a message has three components: Here are two lines of code from the ClickMe class:
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
Both are messages from the ClickMe object to an object named g2d — a Graphics2D object that is essential for painting onscreen. This object is provided to the component when the painting system instructs the component to paint itself. The first line sets the color to white; the second fills a rectangle the size of the component, thus painting the extent of the component's area white.

The following figure highlights each part of the first message to g2d.

The parts of a message in the ClickMe class.

Inheritance in the Example

To paint itself onscreen, an object must be a component. This means that the object must be an instance of a class that derives from the Component class provided by the Java platform.

The ClickMe object is an instance of the ClickMe class, which is declared like this:

public class ClickMe extends JComponent implements MouseListener {
   ...
}
The extends JComponent clause makes ClickMe a subclass of JComponent, a class that derives from the Component class. ClickMe inherits a lot of functionality from Component and JComponent, including the ability to paint itself, to have a standard border around its edges, and to register listeners to be notified of mouse events. Along with these benefits, the ClickMe class has certain obligations: Its painting code must be in a standard place such as the paintComponent method, it must specify its preferred and minimum sizes, and so on:
public ClickMe() {
    ...
    setPreferredSize(aDimensionObject);
    setMinimumSize(anotherDimensionObject);
    ...
}

public void paintComponent(Graphics g) {
    ... // ClickMe's painting code here
}

Interfaces in the Example

The ClickMe component responds to mouse clicks by displaying a spot at the click location. Any object can detect mouse clicks on a component. It just needs to implement the MouseListener interface and register with the component as a mouse listener.

The MouseListener interface declares five methods, each of which is called for a different kind of mouse event: when the mouse is clicked, when the mouse moves outside of the component, and so on. Even though the ClickMe component responds only to mouse clicks, its mouse listener implementation must have all five methods. The methods for the events that the object isn't interested in are empty.

The complete code for the ClickMe component follows. The code that participates in mouse event handling is in colored boldface.

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import java.awt.*;
import java.awt.event.*;

public class ClickMe extends JComponent
                     implements MouseListener {
    private Spot spot = null;
    private static final int RADIUS = 7;
    private Color spotColor = new Color(107, 116, 2); //olive

    /** Creates and initializes the ClickMe component. */
    public ClickMe() {
        addMouseListener(this);
        
        //Hint at good sizes for this component.
        setPreferredSize(new Dimension(RADIUS*30,
                                       RADIUS*15));
        setMinimumSize(new Dimension(RADIUS*4, RADIUS*4));
        
        //Request a black line around this component.
        setBorder(
            BorderFactory.createLineBorder(Color.BLACK));
    }
    
    /**
     * Paints the ClickMe component.  This method is
     * invoked by the Swing component-painting system.
     */
    public void paintComponent(Graphics g) {
        /**
         * Copy the graphics context so we can change it.
         * Cast it to Graphics2D so we can use antialiasing.
         */
        Graphics2D g2d = (Graphics2D)g.create();
        
        //Turn on antialiasing, so painting is smooth.
        g2d.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        
        //Paint the background.
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, getWidth() - 1, getHeight() - 1);

        //Paint the spot.
        if (spot != null) {
            int radius = spot.getSize();
            g2d.setColor(spotColor);
            g2d.fillOval(spot.x - radius, spot.y - radius,
                         radius * 2, radius * 2);
        }
    }

    //Methods required by the MouseListener interface.
    public void mousePressed(MouseEvent event) {
        if (spot == null) {
            spot = new Spot();
            spot.setSize(RADIUS);
        }
        spot.x = event.getX();
        spot.y = event.getY();
        repaint();
    }
    public void mouseClicked(MouseEvent event) {}
    public void mouseReleased(MouseEvent event) {}
    public void mouseEntered(MouseEvent event) {}
    public void mouseExited(MouseEvent event) {}
}

API Documentation

To learn more about how ClickMe works, you need to learn about its superclasses, JComponent and Component. How do you find that information? You can find detailed descriptions of every class in the API documentation, which constitutes the specification for the classes that make up the Java platform.

The API documentation for the Java 2 Platform is online at java.sun.com. It's helpful to have the API documentation for all releases you use bookmarked in your browser. You can find the 5.0 API documentation here:

http://java.sun.com/j2se/5.0/docs/api/ (in the API reference documentation)

To learn more about all the classes and interfaces from the Java platform used by the ClickMe class, you can look at the API documentation for these classes:

A complete discussion of using them to create GUIs is in Creating a GUI with JFC/Swing (in the Learning the Java Language trail).

Summary

This discussion glossed over many details and left some things unexplained, but you should have some understanding now of what object-oriented concepts look like in code. You should now have a general understanding of the following:

Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.