Klasa Component

Drawing

The following figures show the inheritance hierarchies for all the AWT component classes.

        Object
           |
     MenuComponent
           |
     +------------+
     |            |
  MenuItem     MenuBar
     |
   +----+
   |    |
 Menu CheckboxMenuItem
As the figures show, all components except for menu-related components inherit from the AWT Component class. Because of cross-platform restrictions (such as the inability to set menu background colors), menu-related components aren't full-blown Components. Instead, menu components inherit from the AWT MenuComponent class.

When a Java program with a GUI needs to draw itself -- whether for the first time, or in response to becoming unhidden or because its appearance needs to change to reflect something happening inside the program -- it starts with the highest component that needs to be redrawn (for example, the top Component in the hierarchy) and works its way down to the bottom-most Components. This is orchestrated by the AWT drawing system.

In this way, each Component draws itself before any of the Components it contains. This ensures that a Panel's background, for example, is visible only where it isn't covered by one of the Components it contains.

How Drawing Requests Occur

Programs can draw only when the AWT tells them to. The reason is that each occurrence of a Component drawing itself must execute without interruption. Otherwise, unpredictable results could occur, such as a button being drawn halfway, and then being interrupted by some lengthy animation. The AWT orders drawing requests by making them run in a single thread. A Component can use the repaint() method to request to be scheduled for drawing.

The AWT requests that a Component draw itself by invoking the Component's update() method. The default (Component) implementation of the update() method simply clears the Component's background (drawing a rectangle over the component's clipping area in the Component's background color) and then calling the Component's paint() method. The default implementation of the paint() method does nothing.

The Graphics Object

The only argument to the paint() and update() methods is a Graphics object that represents the context in which the Component can perform its drawing. The Graphics class provides methods for the following:

How to Draw

The simplest way for a Component to draw itself is to put drawing code in its paint() method. This means that when the AWT makes a drawing request (by calling the Component's update() method, which is implemented as described above), the Component's entire area is cleared and then its paint() method is called. For programs that don't repaint themselves often, the performance of this scheme is fine.

Important: The paint() and update() methods must execute very quickly! Otherwise, they'll destroy the perceived performance of your program. If you need to perform some lengthy operation as the result of a paint request, do it by starting up another thread (or somehow sending a request to another thread) to perform the operation. For help on using threads, see Threads of Control(in the Writing Java Programs trail).

Below is an example of implementing the paint() method. Both the Converter and ConversionPanel classes draw a box around their area using this code. Both classes also implement an insets() method that specifies the padding around the panels' contents. If they didn't have this method, the box drawn in the paint() method would overlap the external boundaries of the panels' contents.

public void paint(Graphics g) {
    Dimension d = size();
    g.drawRect(0,0, d.width - 1, d.height - 1);
}

Overview of AWT Graphics Support

As you learned from the first lesson in this trail, in the Drawing(in the Creating a User Interface trail) page, the AWT drawing system controls when and how programs can draw. In response to a Component's repaint() method being called, the AWT invokes the Component's update() method to request that the Component redraw itself. The update() method in turn (by default) invokes the Component's paint() method.

An additional wrinkle in this system is that sometimes the AWT calls the paint() method directly, instead of calling update(). This almost always happens as a result of the AWT reacting to an external stimulus, such as the Component first appearing onscreen, or the Component being uncovered by another window. You'll learn more about paint() and update() in the Eliminating Flashing discussion, later in this lesson.

The Graphics Object

The lone argument to the paint() and update() methods is a Graphics(in the API reference documentation) object. Graphics objects are the key to all drawing. They support the two basic kinds of drawing: primitive graphics (such as lines, rectangles, and text) and images. You'll learn about primitive graphics in Using Graphics Primitives. You'll learn about images in Using Images.

Besides supplying methods to draw primitive graphics and images to the screen, a Graphics object provides a drawing context by maintaining state such as the current drawing area and the current drawing color. You can decrease the current drawing area by clipping it, but you can never increase the drawing area. In this way, the Graphics objects ensure that Components can draw only within their own drawing area. You'll learn more about clipping in Overriding the update() Method.

The Coordinate System

Each Component has its own integer coordinate system, ranging from (0, 0) to (width - 1, height - 1), with each unit representing the size of one pixel. As the following figure shows, the upper left corner of the Component's drawing area is (0, 0). The X coordinate increases to the right, and the Y coordinate increases downward.

The Four Forms of the repaint() Method

Remember that programs can call a Component's repaint() method to request that the AWT call the Component's update() method. Here are descriptions of the four forms of the repaint() method:
public void repaint()
Requests that the AWT call the Component's update() method as soon as possible. This is the most frequently used form of repaint().
public void repaint(long time)
Requests that the AWT call the Component's update() method as much as time milliseconds from now.
public void repaint(int x, int y, int width, int height)
Requests that the AWT call the Component's update() method as soon as possible, but repaint only the specified part of the component.
public void repaint(long time, int x, int y, int width, int height)
Requests that the AWT call the Component's update() method as much as time milliseconds from now, but repaint only the specified part of the component.

Jerzy Bobiński - Gdańsk 03.05.1998