Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Page And Component Classes

What's the difference between a page and a component?

There's very little difference between the two. Pages clases must be in the root-package.pages package; components must be in the
root-package.components. Pages may provide event handlers for certain page-specific events (such as activate and passivate). Components may have parameters.

...

Limiting fields to private means that Tapestry can do the necessary processing one class at a time, as needed, at runtime. More complex
Aspect Orient Programming systems such as AspectJ can perform similar transformations (and much more complex ones), but requires a dedicated build step (or the introduction of a JVM agent).

Why don't my informal parameters show up?

Getting informal parameters to work is in two steps. First, you must make a call to the ComponentResources.renderInformalParameters() method, but just as importantly, you must tell Tapestry that you want the component to support
informal parameters, using the SupportsInformalParameters annotation. Here's a hypothetical component that displays an image based on the value of a Image object (presumably, a database entity):

Code Block
@SupportsInformalParameters
public class DBImage
{
  @Parameter(required=true)
  private Image image;

  @Inject
  private ComponentResources resources;

  boolean beginRender(MarkupWriter writer)
  {
    writer.element("img", "src", image.toClientURL(), "class", "db-image");

    resources.renderInformalParameters(writer);

    writer.end();

    return false;
  }
}

Why do I get ClassCastExceptions when I invoke public methods of my page classes?

In Tapestry, there are always two versions of page (or component) classes. The first version is the version loaded by standard class loader: the simple POJO version that you wrote.

The second version is much more complicated; it's the transformed version of your code, with lots of extra hooks and changes to allow the class to operate inside Tapestry. This includes implementing
new interfaces and methods, adding new constructors, and changing access to existing fields and methods.

Although these two classes have the same fully qualified class name, they are distinct classes because they are loaded by different class loaders.