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 <heue...@gmail.com> 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 <allain.lalo...@gmail.com>
>
> >> 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 <nigel.tamp...@f2s.com> 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to