You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Mike Snare <mi...@gmail.com> on 2006/03/14 20:44:37 UTC

Persistent component properties

I posted this Sunday on the user list but got no response, which is
why I am cross-posting it here.

I'm writing a auto-refresh component that refreshes the page using
javascript and resets the scroll position to the pre-refresh position.
 To do this, I have created a Refresher component.

Quick rundown:

The Refresher component is an extension of BaseComponent.  The
template contains a simple form with 2 hidden fields.  One is used to
track the x-offset of the horizontal scroll bar, and the other is used
to track the vertical offset of the scrollbar.  Their values are bound
to the xCoord and yCoord properties of the Refresher component.  The
template also injects a script.

The script records the x and y offsets into the aforementioned hidden
fields everytime the page moves or the user clicks or types.  It also
resets the x and y offsets during the onLoad method of the page.  at
the end of onLoad, it uses the javascript setTimeout method to submit
the form to a listener in the Refresher component.  The listener does
nothing, but exists just to have a place to submit the form to so that
the x and y coordinates get stored so they can be reset.

The properties that store the x and y coordinates are where I am
having huge problems.

I don't need access to them in the class, so I've just defined them
via property elements in the Refresher.jwc spec.  This works fine --
the page refreshes and all is well.  The problem is that the page(s)
that will use this component have several links/buttons that will
submit to the page and re-display the same page.  After this request
(which does not submit the x and y coordinates as it is part of a
different form) the page should redisplay with the correct scroll
state.  This doesn't happen because, as I mentioned, this other form
doesn't submit the scroll state.

My first attempt was to add persistence to the xCoord and yCoord
properties in the Refresher.jwc via persist="session" attributes on
the properties.  This causes the page to fail with an exception on the
second refresh.  The first refresh works and the scroll state is
correct, but on the second refresh I get an exception saying that the
Refresher component does not have an xCoord property.

Class $Refresher_51 does not contain a property named 'xCoord'.
org.apache.hivemind.util.ClassAdaptor.getPropertyAdaptor(ClassAdaptor.java:136)

Also, If I add abstract accessors to the Refresher class for the x and y coords:
    public abstract int getXCoord();
    public abstract int getYCoord();
I get errors saying that Refresher already has a getXCoord method:

Error at classpath:/package/refresh/Refresher.jwc, line 5, column 134:
Error adding property XCoord to class package.refresh.Refresher:
Unable to add method int getXCoord() to class $Refresher_18: duplicate
method: getXCoord

Can anyone shed some light on what I'm doing wrong?  Other components
use persistence (tableview, treeview) so I know it's possible, clearly
I'm just screwing up.

Tap4, java 1.4.2, tomcat 5.0.28

Any help would be great.

Thanks,
-Mike

UPDATE:

I tried having the containing page pass in a parameter that references
a property of the page that could be used to store the component
properties (not because I thought it was a good idea, I was just
testing) and it still failed on the second refresh with the error
message about the property not existing.

I have managed to work around the issue by rolling my own session
persistence hack based on the page name and the name of the property
being persisted.  I use the pageAttach and detach methods in the
component to update/retrieve the values for use in the current cycle. 
It still doesn't answer the question of why this doesn't work.

If I use ONLY abstract accessors/mutators it works fine.  If I use
ONLY property elements in the jwc it works fine.  If I use both (which
should be perfectly possible) It pukes with the duplicate element
exception.

Even if I ONLY use the property elements in the jwc it pukes (property
not found) if I set the persist to anything other than the default.

Thanks,
-Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org


Re: Persistent component properties

Posted by Jesse Kuhnert <jk...@gmail.com>.
Oops..What howard said sounds much more helpful :)

P.S. It looks like you are having a lot of fun writing this component, but
either way I can't help but think that your issue might be more easily
solved using some of the infrastructure provided at
http://tacos.sourceforge.net.

The abillity to do "exactly" what you are doing isn't provided as a
component ~yet~, but it is very easily done via dojo's "Timer" object. (
dojo.lang.Timer) It's basically a javascript equivalent to java.lang.Thread.

If you do decide to do it this way I'd be interested in helping with some
guidance on the tacos mailing lists, as I think this sort of functionality
would be directly applicable in a lot of scenerios. It might be something
tacos should provide officially.

On 3/14/06, Jesse Kuhnert <jk...@gmail.com> wrote:
>
> What happens if you run this without caching disabled?
>
> On 3/14/06, Mike Snare <mi...@gmail.com> wrote:
>
> > I posted this Sunday on the user list but got no response, which is
> > why I am cross-posting it here.
> >
> > I'm writing a auto-refresh component that refreshes the page using
> > javascript and resets the scroll position to the pre-refresh position.
> > To do this, I have created a Refresher component.
> >
> > Quick rundown:
> >
> > The Refresher component is an extension of BaseComponent.  The
> > template contains a simple form with 2 hidden fields.  One is used to
> > track the x-offset of the horizontal scroll bar, and the other is used
> > to track the vertical offset of the scrollbar.  Their values are bound
> > to the xCoord and yCoord properties of the Refresher component.  The
> > template also injects a script.
> >
> > The script records the x and y offsets into the aforementioned hidden
> > fields everytime the page moves or the user clicks or types.  It also
> > resets the x and y offsets during the onLoad method of the page.  at
> > the end of onLoad, it uses the javascript setTimeout method to submit
> > the form to a listener in the Refresher component.  The listener does
> > nothing, but exists just to have a place to submit the form to so that
> > the x and y coordinates get stored so they can be reset.
> >
> > The properties that store the x and y coordinates are where I am
> > having huge problems.
> >
> > I don't need access to them in the class, so I've just defined them
> > via property elements in the Refresher.jwc spec.  This works fine --
> > the page refreshes and all is well.  The problem is that the page(s)
> > that will use this component have several links/buttons that will
> > submit to the page and re-display the same page.  After this request
> > (which does not submit the x and y coordinates as it is part of a
> > different form) the page should redisplay with the correct scroll
> > state.  This doesn't happen because, as I mentioned, this other form
> > doesn't submit the scroll state.
> >
> > My first attempt was to add persistence to the xCoord and yCoord
> > properties in the Refresher.jwc via persist="session" attributes on
> > the properties.  This causes the page to fail with an exception on the
> > second refresh.  The first refresh works and the scroll state is
> > correct, but on the second refresh I get an exception saying that the
> > Refresher component does not have an xCoord property.
> >
> > Class $Refresher_51 does not contain a property named 'xCoord'.
> > org.apache.hivemind.util.ClassAdaptor.getPropertyAdaptor(
> > ClassAdaptor.java:136)
> >
> > Also, If I add abstract accessors to the Refresher class for the x and y
> > coords:
> >     public abstract int getXCoord();
> >     public abstract int getYCoord();
> > I get errors saying that Refresher already has a getXCoord method:
> >
> > Error at classpath:/package/refresh/Refresher.jwc, line 5, column 134:
> > Error adding property XCoord to class package.refresh.Refresher:
> > Unable to add method int getXCoord() to class $Refresher_18: duplicate
> > method: getXCoord
> >
> > Can anyone shed some light on what I'm doing wrong?  Other components
> > use persistence (tableview, treeview) so I know it's possible, clearly
> > I'm just screwing up.
> >
> > Tap4, java 1.4.2, tomcat 5.0.28
> >
> > Any help would be great.
> >
> > Thanks,
> > -Mike
> >
> > UPDATE:
> >
> > I tried having the containing page pass in a parameter that references
> > a property of the page that could be used to store the component
> > properties (not because I thought it was a good idea, I was just
> > testing) and it still failed on the second refresh with the error
> > message about the property not existing.
> >
> > I have managed to work around the issue by rolling my own session
> > persistence hack based on the page name and the name of the property
> > being persisted.  I use the pageAttach and detach methods in the
> > component to update/retrieve the values for use in the current cycle.
> > It still doesn't answer the question of why this doesn't work.
> >
> > If I use ONLY abstract accessors/mutators it works fine.  If I use
> > ONLY property elements in the jwc it works fine.  If I use both (which
> > should be perfectly possible) It pukes with the duplicate element
> > exception.
> >
> > Even if I ONLY use the property elements in the jwc it pukes (property
> > not found) if I set the persist to anything other than the default.
> >
> > Thanks,
> > -Mike
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
> >
> >
>

Re: Persistent component properties

Posted by Jesse Kuhnert <jk...@gmail.com>.
What happens if you run this without caching disabled?

On 3/14/06, Mike Snare <mi...@gmail.com> wrote:
>
> I posted this Sunday on the user list but got no response, which is
> why I am cross-posting it here.
>
> I'm writing a auto-refresh component that refreshes the page using
> javascript and resets the scroll position to the pre-refresh position.
> To do this, I have created a Refresher component.
>
> Quick rundown:
>
> The Refresher component is an extension of BaseComponent.  The
> template contains a simple form with 2 hidden fields.  One is used to
> track the x-offset of the horizontal scroll bar, and the other is used
> to track the vertical offset of the scrollbar.  Their values are bound
> to the xCoord and yCoord properties of the Refresher component.  The
> template also injects a script.
>
> The script records the x and y offsets into the aforementioned hidden
> fields everytime the page moves or the user clicks or types.  It also
> resets the x and y offsets during the onLoad method of the page.  at
> the end of onLoad, it uses the javascript setTimeout method to submit
> the form to a listener in the Refresher component.  The listener does
> nothing, but exists just to have a place to submit the form to so that
> the x and y coordinates get stored so they can be reset.
>
> The properties that store the x and y coordinates are where I am
> having huge problems.
>
> I don't need access to them in the class, so I've just defined them
> via property elements in the Refresher.jwc spec.  This works fine --
> the page refreshes and all is well.  The problem is that the page(s)
> that will use this component have several links/buttons that will
> submit to the page and re-display the same page.  After this request
> (which does not submit the x and y coordinates as it is part of a
> different form) the page should redisplay with the correct scroll
> state.  This doesn't happen because, as I mentioned, this other form
> doesn't submit the scroll state.
>
> My first attempt was to add persistence to the xCoord and yCoord
> properties in the Refresher.jwc via persist="session" attributes on
> the properties.  This causes the page to fail with an exception on the
> second refresh.  The first refresh works and the scroll state is
> correct, but on the second refresh I get an exception saying that the
> Refresher component does not have an xCoord property.
>
> Class $Refresher_51 does not contain a property named 'xCoord'.
> org.apache.hivemind.util.ClassAdaptor.getPropertyAdaptor(ClassAdaptor.java
> :136)
>
> Also, If I add abstract accessors to the Refresher class for the x and y
> coords:
>     public abstract int getXCoord();
>     public abstract int getYCoord();
> I get errors saying that Refresher already has a getXCoord method:
>
> Error at classpath:/package/refresh/Refresher.jwc, line 5, column 134:
> Error adding property XCoord to class package.refresh.Refresher:
> Unable to add method int getXCoord() to class $Refresher_18: duplicate
> method: getXCoord
>
> Can anyone shed some light on what I'm doing wrong?  Other components
> use persistence (tableview, treeview) so I know it's possible, clearly
> I'm just screwing up.
>
> Tap4, java 1.4.2, tomcat 5.0.28
>
> Any help would be great.
>
> Thanks,
> -Mike
>
> UPDATE:
>
> I tried having the containing page pass in a parameter that references
> a property of the page that could be used to store the component
> properties (not because I thought it was a good idea, I was just
> testing) and it still failed on the second refresh with the error
> message about the property not existing.
>
> I have managed to work around the issue by rolling my own session
> persistence hack based on the page name and the name of the property
> being persisted.  I use the pageAttach and detach methods in the
> component to update/retrieve the values for use in the current cycle.
> It still doesn't answer the question of why this doesn't work.
>
> If I use ONLY abstract accessors/mutators it works fine.  If I use
> ONLY property elements in the jwc it works fine.  If I use both (which
> should be perfectly possible) It pukes with the duplicate element
> exception.
>
> Even if I ONLY use the property elements in the jwc it pukes (property
> not found) if I set the persist to anything other than the default.
>
> Thanks,
> -Mike
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>
>

Re: Persistent component properties

Posted by Howard Lewis Ship <hl...@gmail.com>.
getXCoord() --> property name = "XCoord" not "xCoord"

This is a common mistake, but this behavior is goverened by the Java
Beans specification.

Another reason to like annotations :-)

On 3/14/06, Mike Snare <mi...@gmail.com> wrote:
> I posted this Sunday on the user list but got no response, which is
> why I am cross-posting it here.
>
> I'm writing a auto-refresh component that refreshes the page using
> javascript and resets the scroll position to the pre-refresh position.
>  To do this, I have created a Refresher component.
>
> Quick rundown:
>
> The Refresher component is an extension of BaseComponent.  The
> template contains a simple form with 2 hidden fields.  One is used to
> track the x-offset of the horizontal scroll bar, and the other is used
> to track the vertical offset of the scrollbar.  Their values are bound
> to the xCoord and yCoord properties of the Refresher component.  The
> template also injects a script.
>
> The script records the x and y offsets into the aforementioned hidden
> fields everytime the page moves or the user clicks or types.  It also
> resets the x and y offsets during the onLoad method of the page.  at
> the end of onLoad, it uses the javascript setTimeout method to submit
> the form to a listener in the Refresher component.  The listener does
> nothing, but exists just to have a place to submit the form to so that
> the x and y coordinates get stored so they can be reset.
>
> The properties that store the x and y coordinates are where I am
> having huge problems.
>
> I don't need access to them in the class, so I've just defined them
> via property elements in the Refresher.jwc spec.  This works fine --
> the page refreshes and all is well.  The problem is that the page(s)
> that will use this component have several links/buttons that will
> submit to the page and re-display the same page.  After this request
> (which does not submit the x and y coordinates as it is part of a
> different form) the page should redisplay with the correct scroll
> state.  This doesn't happen because, as I mentioned, this other form
> doesn't submit the scroll state.
>
> My first attempt was to add persistence to the xCoord and yCoord
> properties in the Refresher.jwc via persist="session" attributes on
> the properties.  This causes the page to fail with an exception on the
> second refresh.  The first refresh works and the scroll state is
> correct, but on the second refresh I get an exception saying that the
> Refresher component does not have an xCoord property.
>
> Class $Refresher_51 does not contain a property named 'xCoord'.
> org.apache.hivemind.util.ClassAdaptor.getPropertyAdaptor(ClassAdaptor.java:136)
>
> Also, If I add abstract accessors to the Refresher class for the x and y coords:
>     public abstract int getXCoord();
>     public abstract int getYCoord();
> I get errors saying that Refresher already has a getXCoord method:
>
> Error at classpath:/package/refresh/Refresher.jwc, line 5, column 134:
> Error adding property XCoord to class package.refresh.Refresher:
> Unable to add method int getXCoord() to class $Refresher_18: duplicate
> method: getXCoord
>
> Can anyone shed some light on what I'm doing wrong?  Other components
> use persistence (tableview, treeview) so I know it's possible, clearly
> I'm just screwing up.
>
> Tap4, java 1.4.2, tomcat 5.0.28
>
> Any help would be great.
>
> Thanks,
> -Mike
>
> UPDATE:
>
> I tried having the containing page pass in a parameter that references
> a property of the page that could be used to store the component
> properties (not because I thought it was a good idea, I was just
> testing) and it still failed on the second refresh with the error
> message about the property not existing.
>
> I have managed to work around the issue by rolling my own session
> persistence hack based on the page name and the name of the property
> being persisted.  I use the pageAttach and detach methods in the
> component to update/retrieve the values for use in the current cycle.
> It still doesn't answer the question of why this doesn't work.
>
> If I use ONLY abstract accessors/mutators it works fine.  If I use
> ONLY property elements in the jwc it works fine.  If I use both (which
> should be perfectly possible) It pukes with the duplicate element
> exception.
>
> Even if I ONLY use the property elements in the jwc it pukes (property
> not found) if I set the persist to anything other than the default.
>
> Thanks,
> -Mike
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>
>


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org


Re: Persistent component properties

Posted by Mike Snare <mi...@gmail.com>.
@Howard:

That was it.  It seems wierd though.  Any chance this quirk could be
documented in the property element reference.  Sure, it's not a
tapestry specific issue but it seems worh the screen space.  According
to the sun spec it's because the first 2 letters of the getter/setter
are both uppercase so the property name is left as is.

It could at least be added to the gotchas list on the wiki.

Thanks for the help!

@Jesse

Thanks for the hint about tacos.  During the initial release for the
product we're not too worried about flashing it up too much, that will
come in the second phase.  Until then we'd rather not introduce more
libraries than are absolutely necessary.

As an aside, I managed to split out the Refresher and AutoScroll
component into independent components, with the Refresher working as
described earlier and the AutoScroll submitting x and y coordinates
via ajax (XTile) as they change (as they do after onScroll events) so
no form submission is necessary.

@All

Is there a reason that the XTile component is not documented on the
website?  I stumbled across it looking for something else and found it
insanely useful.  I realize it's documented with an example on the
t-deli site, but since it's included in the contrib library...

Thanks again for the help,
-Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org