Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: User Interface Design
Expertise: Beginner
Mar 21, 1997

'Smart' Painting

Question:
It isn't clear to me how to do 'smart' painting. For example, if I want to paint only a portion of something, what should I do?

There are paint/repaint methods that take arguments such as x,y, etc. Who or what calls these methods? Are they provided just as convenient places for overrides? Am I supposed to override one of the multi-argument paints, save the x,y args etc., and then let paint(Graphics g) take over from there?

It seems I'm forever putting 'printf's inside these methods in order to determine the timing and ordering of who calls what when.

Answer:
The Component class contains a single Component.paint() method:

public void paint(Graphics g);
This method is abstract; you must provide a definition of paint in the component subclasses you define. Although you define the paint method, you don't call it. This is done by the Component.update() method:
public void update(Graphics g) {
   clearBackground(); // draw rect over component in bgrnd color
   paint(g);
 }
 
Actually, you don't call the update method either. Instead, you call one of the four Component repaint methods; these dig up the component's graphics context, g, then ask AWT to call update(g).

One of these methods:

   public void repaint(int x, int y, int w, int h) { ... }
 
only redraws the portion of the component in the rectangle with upper left corner at position (x, y), height = h, and width = w.

Here's an example of this method in action:

Click the "repaint" button several times and watch the rectangle on the left turn green, while the rectangle on the right remains black. Next, hide the frame behind a window, then unhide it. This time both rectangles will be the same shade of green:

************************/

import java.awt.*;

public class MyComponent extends Frame {

   private int r = 0, g = 0, b = 0; // rgb colors

   public void paint(Graphics gr) {
      r = (r + 10) % 255;
      g = (g + 10) % 255;
      gr.setColor(new Color(r, g, b));
      gr.fillRect(10, 50, 50, 50);
      gr.fillRect(150, 50, 50, 50);
   }

   public MyComponent() {
      setTitle("Test");
      setLayout(new FlowLayout());
      add(new Button("repaint"));
   }

   public boolean action(Event e, Object what) {
      if (what.equals("repaint")) repaint(0, 0, 100, 100);
      return super.action(e, what);
   }

   public static void main(String[] args) {
      Frame mc = new MyComponent();
      mc.resize(300, 300);
      mc.show();
   }

}

/**************** 
The Component.paint() method is called for one of three reasons:
  1. the first time the component appears
  2. in response to the component becoming unhidden
  3. because repaint() was explicitly called
We have already seen that repaint() asks AWT to call update(). What this means is that AWT creates a thread containing a call to update(). This can create confusion because the main thread can continue before the call to update() terminates.

In the second case, AWT calls the paint() method directly, skipping the call to update(). Also, if the component is a container, then after its paint() method is called, the paint() methods of each component inside the container are called, but in no particular order!

DevX Pro
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date