paint() vs. update()
Why do we make a distinction between "system-triggered" and. "app-triggered" painting? Because AWT treats each of these cases slightly differently for heavyweight components (the lightweight case will be discussed later), which is unfortunately a source of great confusion.
For heavyweight components, these two types of painting happen in the two distinct ways, depending on whether a painting operation is system-triggered or app-triggered.
System-triggered painting
This is how a system-triggered painting operation takes place:
The AWT determines that either part or all of a component needs to be painted.
The AWT causes the event dispatching thread to invoke paint() on the component.
App-triggered painting
An app-triggered painting operation takes place as follows:
The program determines that either part or all of a component needs to be repainted in response to some internal state change.
The program invokes repaint() on the component, which registers an asynchronous request to the AWT that this component needs to be repainted.
The AWT causes the event dispatching thread to invoke update() on the component.
NOTE: If multiple calls to repaint() occur on a component before the initial repaint request is processed, the multiple requests may be collapsed into a single call to update(). The algorithm for determining when multiple requests should be collapsed is implementation-dependent. If multiple requests are collapsed, the resulting update rectangle will be equal to the union of the rectangles contained in the collapsed requests.
If the component did not override update(), the default implementation of update() clears the component's background (if it's not a lightweight component) and simply calls paint().
Since by default, the final result is the same (paint() is called), many people don't understand the purpose of having a separate update() method at all. While it's true that the default implementation of update() turns around and calls paint(), this update "hook" enables a program to handle the app-triggered painting case differently, if desired. A program must assume that a call to paint() implies that the area defined by the graphic's clip rectangle is "damaged" and must be completely repainted, however a call to update() does not imply this, which enables a program to do incremental painting.
Incremental painting is useful if a program wishes to layer additional rendering on top of the existing bits of that component. The UpdateDemo example demonstrates a program which benefits from using update() to do incremental painting.
In truth, the majority of GUI components do not need to do incremental drawing, so most programs can ignore the update() method and simply override paint() to render the component in it's current state. This means that both system-triggered and app-triggered rendering will essentially be equivelent for most component implementations.