Right. This is the default behaviour for repaint() on a Node. it will group all the repaint requests together that occur within a UI Cycle.
2009/11/3 Nigel <[email protected]> > > I agree, my interpretation is that calling invalidatePaint should > result in a repaint sometime soon after. > > This differs from Piccolos current (wrong?) behaviour whereby calling > invalidatePaint does not result in a repaint (unless some other event > triggers the repaint). > > My gut feel is that there's a timer missing somewhere. > > It seems the invalidatePaint() message propagates up the node > hierarchy to the PLayer, but is then ignored by the camera, whereas I > think the camera should notice the invalidatePaint and if after a > reasonable time delay (say 1/10th second) should trigger a repaint if > a repaint hasn't already occurred anyway. > > This would allow Piccolo to combine multiple paints into fewer paints, > especially effective when large numbers of overlapping nodes all need > to be redrawn at about the same time. > > Nigel > > > > On Nov 3, 6:03 am, Michael Heuer <[email protected]> wrote: > > 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#invalid... > > > > 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 -~----------~----~----~----~------~----~------~--~---
