devxlogo

‘Smart’ Painting

‘Smart’ Painting

Question:
It isn’t clear to me how to do ‘smart’ painting. For example, ifI 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 orwhat calls these methods? Are they provided just as convenient placesfor overrides? Am I supposed to override one of the multi-argumentpaints, 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 inorder 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 definitionof paint in the component subclasses you define. Although you definethe paint method, you don’t call it. This is done bythe 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 callone of the four Component repaint methods; these dig up the component’sgraphics context, g, then ask AWT to callupdate(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 upperleft 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 theleft turn green, while the rectangle on the right remains black. Next, hidethe frame behind a window, then unhide it. This time both rectangles willbe 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 ofthree 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 callupdate().What this means is that AWT creates a thread containing a callto update(). This can create confusion because the main threadcan 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 isa container, then after its paint() method is called, thepaint() methods of each component inside the container arecalled, but in no particular order!

devx-admin

Share the Post: