I think this is supposed to be analogous to the AWT Component.invalidate() method
http://java.sun.com/javase/6/docs/api/java/awt/Container.html#invalidate%28%29 A client might call invalidatePaint() a lot of times before an actual repaint happens. michael Allain Lalonde wrote: > It would seem that indeed, this behavior is intended, though I can't see > why? > invalidatePaint() is used to flag nodes as needing a repaint, but the method > that is primarily responsible for making use of that flag is > validateFullPaint() which is only gets called from PRoot.processInputs(). > > It seems that calling repaint does the same thing, but is correctly handled > by Swing since it you follow the execution path ultimately, it ends up > callingin 'component.repaint(...);'. > > Can someone shed some light on why this is the way it's written? > > It would seem to me that a call to repaint() is needed at the end of > invalidatePaint() so that the need for repainting bubbles up to the > underlying Component. > > > 2009/11/2 Allain Lalonde <[email protected]> >> >> Good eye, invalidate paint just flags the node as needing to be >> repainted. This gets picked up on the next ui cycle. I don't believe >> that it will automatically bubble up the stack, though i will need to >> re-read the code to confirm this. I will examine your code when i get >> home to see if i can repelicate your issue. >> >> Thank you for bringing this up. >> >> On 02/11/2009, Nigel <[email protected]> wrote: >> > >> > >> > The comment in PNode.java reads >> > >> > // When you do create you own nodes the only method that you will >> > // normally need to call is invalidatePaint. This method marks the >> > // nodes as having invalid paint, the root node's UI cycle will >> > then >> > // later discover this damage and report it to the Java repaint >> > manager. >> > >> > >> > However, I find that after calling invalidatepaint() the repaint >> > manager does not discover the damage unless other events are occurring >> > (such as moving the mouse around). >> > >> > I was expecting that calling invalidatePaint would result in the node >> > being repainted some time later - am I doing something wrong or is >> > Piccolo? >> > >> > >> > Here is a contrived example (ClockNode.java) - It displays 4 custom >> > nodes, each showing a clock's second hand. The top 2 clocks are >> > updated from within the event dispatch thread, the lower 2 clocks are >> > updated from another thread. The 2 clocks on the left are redrawn via >> > a call to repaint and the 2 on the right via a call to >> > invalidatePaint. >> > >> > if you run it you'll see the clock on the right (calling >> > invalidatePaint) are only redrawn if you are moving your mouse over >> > the window. >> > >> > ClockNode.java >> > >> > import java.awt.*; >> > import java.awt.geom.*; >> > import edu.umd.cs.piccolo.*; >> > import edu.umd.cs.piccolo.util.*; >> > >> > import edu.umd.cs.piccolox.PFrame; >> > >> > public class ClockNode extends PNode { >> > >> > private GeneralPath secondHand; >> > private int tseconds; // 10ths of seconds >> > >> > public void tick() { >> > tseconds++; >> > if ( tseconds >= 600 ) { tseconds = 0; } >> > // inform Piccolo that the node needs to be redrawn >> > if ( useRepaint ) { >> > repaint(); >> > } else { >> > invalidatePaint(); >> > } >> > } >> > >> > private boolean useRepaint; >> > public ClockNode(boolean useRepaint) { >> > this.useRepaint = useRepaint; >> > // create the needle shape >> > secondHand = new GeneralPath(GeneralPath.WIND_EVEN_ODD); >> > secondHand.moveTo(-0.1,0); >> > secondHand.lineTo(0,1); >> > secondHand.lineTo(0.1,0); >> > secondHand.closePath(); >> > } >> > >> > public void paint(PPaintContext aPaintContext) { >> > Graphics2D g2 = >> > (Graphics2D)aPaintContext.getGraphics().create(); // >> > create - as we mess with the transform >> > g2.setPaint(Color.BLACK); >> > //draw the face >> > g2.draw( new Ellipse2D.Double( getX(), getY(), getWidth(), >> > getHeight >> > () )); >> > //draw the second hand >> > g2.translate(getX()+getWidth()/2,getY()+getHeight()/2); // >> > translate >> > hand so 0,0 is centre of bounds >> > g2.scale(getWidth()/2,getHeight()/2); // scale the needle >> > g2.rotate ( Math.toRadians((tseconds*6)/10f+180) ); >> > g2.fill(secondHand); >> > } >> > >> > public static void main(String args[]) { >> > // top left clock - uses repaint >> > final ClockNode clockNode1 = new ClockNode(true); >> > clockNode1.setBounds(0,0,200,200); >> > // top right clock - uses invalidatePaint >> > final ClockNode clockNode2 = new ClockNode(false); >> > clockNode2.setBounds(210,0,200,200); >> > // lower left clock - uses repaint >> > final ClockNode clockNode3 = new ClockNode(true); >> > clockNode3.setBounds(0,210,200,200); >> > // lower right clock - uses invalidatePaint >> > final ClockNode clockNode4 = new ClockNode(false); >> > clockNode4.setBounds(210,210,200,200); >> > >> > PFrame pFrame = new PFrame() { >> > public void initialize() { >> > >> > getCanvas().getLayer().addChild(clockNode1); >> > >> > getCanvas().getLayer().addChild(clockNode2); >> > >> > getCanvas().getLayer().addChild(clockNode3); >> > >> > getCanvas().getLayer().addChild(clockNode4); >> > setSize(500,500); >> > } >> > }; >> > >> > // tick clocks 1 and 2 in the event dispatch thread >> > new javax.swing.Timer(100, new >> > java.awt.event.ActionListener() { >> > public void actionPerformed >> > (java.awt.event.ActionEvent evt) { >> > clockNode1.tick(); >> > clockNode2.tick(); >> > } >> > }).start(); >> > >> > // tick clocks 3 and 4 in the timer thread >> > java.util.Timer timer = new java.util.Timer(true); >> > timer.schedule( new java.util.TimerTask() { >> > public void run() { >> > clockNode3.tick(); >> > clockNode4.tick(); >> > } >> > },0,100); >> > } >> > >> > } >> > > >> > > > > > > --~--~---------~--~----~------------~-------~--~----~ Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en -~----------~----~----~----~------~----~------~--~---
