Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Since Wicket allows us so much freedom to focus on Java code, and not messy taglibs or other such issues, it makes sense to further abstract it away by adding Javascript to our pages using Wicket Behaviors.

In this example, we'll be using the SWFObject from http://blog.deconcept.com/swfobject/.

To begin, lets make sure and copy in our swfobject.js file next to our new AbstractBehavior. And then create our SWFObject.java file like so:

Code Block
public class SWFObject extends AbstractBehavior {

  ...

}

We extend AbstractBehavior and automatically get the ability to override methods that will help us in our cause, i.e. IHeaderContributor and of course IBehavior.

Adding the Javascript as a ResourceReference to your Behavior

In the code below, we can add our Javascript to our Wicket Behavior in the following manner:

Code Block

    private static final CompressedResourceReference SWFOBJECT_JS = new CompressedResourceReference(
            SWFObject.class, "swfobject.js");

Adding the Javascript to the head of the page

Because we have extended AbstractBehavior, we can add items to the HTML head element by providing our own implementation of renderHeader method:

Code Block

    public void renderHead(IHeaderResponse response) {
        response.renderJavascriptReference(SWFOBJECT_JS);
    }

The above code will create the proper HTML linkage to our Javascript file within our package. As an added bonus, when the project is deployed to production, the resource (javascript) will be compressed for bandwidth savings.

Rendering the Javascript

Here we'll provide our implementation of onRendered(Component component) so we can place our Javascript code with references to the component we're providing behavior for:

Code Block

    public void onRendered(Component component) {
        Response response = component.getResponse();  // 1
        final String id = component.getMarkupId();    // 2
        final String swfVar = id + "SWF";

        response.write(JavascriptUtils.SCRIPT_OPEN_TAG);  // 3

        response.write("var " + swfVar + " = new SWFObject('" + flashUrl + "', '" 
          + id + "', '" + width + "', '" + height + "', '" + version + "', '" + backgroundColor + "');");  // 4
        if (getParameters() != null && getParameters().size() > 0) {
            for (Map.Entry<String, String> e : getParameters().entrySet()) {
                response.write(swfVar + ".addParam('" + e.getKey() + "', '" + e.getValue() + "');");
            }
        }
        if (getVariables() != null && getVariables().size() > 0) {
            for (Map.Entry<String, String> e : getVariables().entrySet()) {
                response.write(swfVar + ".addVariable('" + e.getKey() + "', '" + e.getValue() + "');");
            }
        }

        response.write(swfVar + ".write('" + id + "');");  // 5
        response.write(JavascriptUtils.SCRIPT_CLOSE_TAG);  // 6
    }

Here's what we're doing here in a nutshell

  1. We get a reference to the Response object from our Component
  2. Grab the id of our HTML element we will be referencing
  3. Use the handy JavascriptUtils.SCRIPT_OPEN_TAG to write out our script header
  4. Write out the Javascript we'd like to add to our page
  5. We use the id object gathered earlier to use in our Javascript
  6. Close off the script with the utility method

Here's a quick list of how you can get your Javascript rendered in the correct place:

  • In the head tag, you would provide your implementation in renderHead
  • Just after our component render, you would override onRendered or rendered as in the code example above
  • Just before our component render, you would override onComponentTag

Adding this behavior to our Page

Here's how you would probably add this to your page, in the case of this SWFObject, here's what the HTML most likely would look like

Code Block
html
html
        <div wicket:id="myFlashMovie" id="myFlashMovie">
            [myFlashMovie]
        </div>

And in our Java code, we provide the following, note the use of Label here, to take advantage of pushing SEO data into the page rather than a messy embed / object call:

Code Block
new Label(this, "myFlashMovie", "Example of adding SWFObject to render our Flash movie")
      .add(new SWFObject("http://www.adobe.com/support/flash/ts/documents/wmode/wmode_example.swf",
                        150, 150,
                        "6", "#000000");

Thats all there is to it. Please note that the example above is using Wicket 2.0, but can be easily backported to 1.x. In addition, the full implementation has support for adding parameters and variables which is part of the swfobject.js library.

For the full implementation of the SWFObject behavior please reference this JIRA issue: http://issues.apache.org/jira/browse/WICKET-309