How come this InfiniteProgress.paintComponent() loops forever ????

S

Spendius

Hi,
I found this class in comp.lang.java.gui, in a 2-year old thread.
Can someone explain me how it is that this class keeps looping
through its paintComponent() method ?!? I added a System.out.
println at the end of every method and numbered these calls (in
the order in which they appear in the file) to try to understand
what happens and saw that it loops as follows:
1 end constructor
5 getTimer
3 addNotify
2 isFocusable
2 isFocusable
2 isFocusable
2 isFocusable
2 isFocusable
in 9: if hasFocus()
9 end paintComponent
8 end actionPerformed
in 9: if hasFocus()
9 end paintComponent
8 end actionPerformed
in 9: if hasFocus()
9 end paintComponent
8 end actionPerformed
in 9: if hasFocus()
Yet I just call its constructor in my JFrame without any
further call to any of its methods. How come this getTimer()
gets automatically called, and then addNotify() etc. to
eventually end up looping in paintComponent() ???

Thanks !
Spendius


/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the
Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
* Microsystems, Inc. All Rights Reserved.
*/

package org.netbeans.core;

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

/** Infinite progress bar.
* Taken from NetBeans ;)( to be exactly form
org.netbeans.core.ExitDialog ).
* @author Ian Formanek, Petr Hrebejk
*/
public final class InfiniteProgress extends JPanel implements
ActionListener {

/** Swing timer used to repaint the component. */
private Timer timer;

// XXX There could be a nicer repainting policy created for sure.
/** Index indicating current position of gap whitin a drawing
block. */
private int index;
/** Index of gap whitin a block. */
private int gapIndex;
/** Width of one cell in the block. */
private int cellWidth;


/** Constructs infinite progress. */
public InfiniteProgress() {
this.gapIndex = 4;
//this.cellWidth = getFontMetrics(getFont()).charWidth('n');
this.cellWidth = 3;

setBorder(BorderFactory.createEtchedBorder());
setForeground(UIManager.getColor("Label.foreground")); //
NOI18N

setPreferredSize(new Dimension(200,16));
setDoubleBuffered(true);

}

/** Indicates whether the component can receive focus. Overrides
* superclass method.
* @return <code>true</code> */
public boolean isFocusTraversable() {
return true;
}

/** Overrides superclass method. Adds starting of timer. */
public void addNotify() {
super.addNotify();

getTimer().start();
}

/** Overrides superclass method. Adds stopping of timer. */
public void removeNotify() {
getTimer().stop();

super.removeNotify();
}

/** Gets timer. */
private synchronized Timer getTimer() {
if(timer == null) {
timer = new Timer(30, this);
}

return timer;
}

/** Implements <code>ActionPerformed</code> interface. */
public void actionPerformed(ActionEvent evt) {
index++;
if(index >= gapIndex) {
index = 0;
}

repaint();
}

/** Overrides supeclass method. Adds painting of progress. */
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
Rectangle rect = g2.getClipBounds();

g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_SPEED);
//g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//g2.setPaint(new GradientPaint(0,0, getForeground(), 0,
rect.height, getBackground()));
g2.setPaint(new GradientPaint(0,0, getForeground(),
rect.width*0.9f, rect.height, getBackground()));
for(int i = 0, pos = 0 ; pos < rect.width; pos += cellWidth,
i++) {
if(i % gapIndex != index) {
g2.fillRect(pos, 0, cellWidth, rect.height);
}
}

if(hasFocus()) {
Color oldColor = g2.getColor();
g2.setColor(UIManager.getColor("Button.focus")); // NOI18N

g2.drawRect(rect.x + 2, rect.y + 2, rect.width - 5,
rect.height - 5);
g2.setColor(oldColor);
}
}
} // End of class InfiniteProgress.
 
C

Chris Uppal

Spendius said:
Can someone explain me how it is that this class keeps looping
through its paintComponent() method ?!?


This method overrides the superclass method to creates and starts a
javax.swing.Timer when the component is added to a container.
public void addNotify() {
super.addNotify();

getTimer().start();
}


The Timer thereafter will call this method of the component every 30
milliseconds.
public void actionPerformed(ActionEvent evt) {
index++;
if(index >= gapIndex) {
index = 0;
}

repaint();
}


The call to repaint() tells Swing/AWT that the component's appearance should
change, so the system schedules calling the component's paintComponent() method
when it is next convenient to do so.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top