The Source for Java Technology Collaboration
User: Password:



Tim Boudreau

Tim Boudreau's Blog

Smooth Sailing in the NetBeans Mobile; Wicket AJAX basics

Posted by timboudreau on September 06, 2007 at 10:28 AM | Comments (5)

After an initial mechanical hiccup, the NetBeans Mobile is purring along nicely, and I'm stopped for the night most of the way across Nevada. Photos from today are available here. It looks like I'll be visiting with members of the Salt Lake City, Utah Java Users' Group on Friday, the Milwaukee, Wisconsin JUG on Monday and the Madison, Wisconsin JUG on Tuesday. If you're along my route, drop me a line!

My friend at Sun, Sharat Chander posted some photos from our adventures in Sacramento yesterday - he came and met me at the truck stop where the alternator was being replaced, and then we found out the parts company sent the one matching alternator they had to the wrong shop. So we zoomed over there, picked it up, brought it back to the truck stop...and found out it was the wrong alternator. Anyway, it all came out well in the end. The folks at the 49er Truck Stop in Sacramento were incredibly nice and helpful! The site requires registration, but I'll post the best-of later.

I need a name for my copilot, the California native poppy plant I'm bringing to Massachusetts for my friend Todd's cousin. Any suggestions?

Unbeknownst to me, the photo rig was off for the lovely drive through the Sierras, into Nevada - the power plug was loose from the laptop. But there are photos, and not all of them are of white lines in the highway. And I know there are friends and family, not to mention people in other countries who are getting to take a vicarious road trip across the U.S. through this. So I'm now keeping the laptop on the dash. I'm going to try to get something working tonight so that I can stick a mouse on the dashboard and press the mouse wheel to trigger taking a picture when there's something interesting to see - the timer works for showing random progress, but it would be nice to be able to have both.

You may have noticed that the site uses AJAX to switch between the table of photos and the full size photos and the comments page. AJAX in Wicket is incredibly easy! You just add an AJAX behavior to the component, and write one method. That method adds any components that should be updated to the AjaxRequestTarget, and replaces them in their parent container with new components with the same ids as the old ones!

Here's an example. We will simply put some text on a page; whenever it is clicked, it updates to say how many times it has been clicked. The code that does the magic is incredibly simple:

package com.myapp.wicket;
import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
public class ExamplePanel extends Panel {
    private int clickCount;
    private Label lbl;
    public ExamplePanel(String id) {
        super(id);
        //Add a simple text label
        lbl = new Label("label", "Click Me");
        add(lbl);
        //Make it clickable via AJAX
        lbl.add(new ClickBehavior());
    }

    private final class ClickBehavior extends AjaxEventBehavior {
        private ClickBehavior() { super("onClick");}
        protected void onEvent(AjaxRequestTarget target) {
            //Make a new label with the same ID as the old one
            Label nue = new Label("label", "Clicked " + (clickCount++) + 
                    " times");
            //This is important, so the label's markup can be rewritten
            nue.setOutputMarkupId(true);
            //Replace the old label with the new one
            ExamplePanel.this.addOrReplace(nue);
            //Add the component to the request target, so the javascript on the
            //client knows to rewrite it in the page DOM
            target.addComponent(nue);
            //Add the same click behavior - to the new component, so it
            //responds to clicks too.  Note we cannot reuse "this" here.
            nue.add(new ClickBehavior());
            lbl = nue;
        }
    }
}
The HTML for it is even simpler:
<html>
  <head>
    <title>Dummy content</title>
  </head>
  <body>
      <wicket:panel>
      <span wicket:id="label">the label</span>
      </wicket:panel>
  </body>
</html>
I've added this example to the sample projects in the NetBeans Wicket Module. Probably the coolest thing about AJAX in Wicket is that for a lot of components, the fallback behavior if the browser doesn't have javascript available is handled for you (e.g. AjaxFallbackLink).

Another thing that is wonderful about Wicket is its debuggability: If you run this example, you'll see a nice little label at the bottom of the browser that says WICKET AJAX DEBUG. Click it and you get a little popup with all sorts of useful logging info.


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • That was some adventure at the truck shop. So when do we get to see the snaps other than the ones with the white lines on the highway? The AJAX setup switching between the pics is really convenient. Add some photography skills and good studio equipment and you could have a great collection of pictures.

    Posted by: j_hell on September 06, 2007 at 10:56 AM

  • hey tim! hope the netbeans mobile keeps running smooth.
    personally, i would use a model to write that ajax code this way:


    import org.apache.wicket.ajax.AjaxEventBehavior;
    import org.apache.wicket.ajax.AjaxRequestTarget;
    import org.apache.wicket.markup.html.basic.Label;
    import org.apache.wicket.markup.html.panel.Panel;
    import org.apache.wicket.model.AbstractReadOnlyModel;

    public class ExamplePanel extends Panel {

    private int clicks = 0;

    public ExamplePanel(final String id) {
    super(id);
    final Label label;
    add(label = new Label("label", new AbstractReadOnlyModel() {
    @Override
    public Object getObject() {
    return clicks == 0 ? "Click me" : "Clicked " + clicks + " time(s)";
    }
    }));
    label.setOutputMarkupId(true);
    label.add(new AjaxEventBehavior("onclick") {
    @Override
    protected void onEvent(AjaxRequestTarget target) {
    clicks++;
    target.addComponent(label);
    }
    });
    }
    }


    Posted by: jonathanlocke on September 07, 2007 at 12:57 AM

  • Ooh, that is simpler. I will update the sample code.

    Posted by: timboudreau on September 07, 2007 at 01:57 AM

  • simpler but also really elegant. you want to do as much as you can in wicket using models and pull methods. for example, instead of calling setVisible, implement isVisible. it's a bit like swing in this respect. and ajax updating is incredibly simple, although i think it's possible to make it even more automatic than it currently is... again by creating a pattern where ajaxy components implement something like isDirty() and the classes being used take care of adding components based on the dirty bits. of course this is overkill for this problem, but at some point it might be worth looking into...

    Posted by: jonathanlocke on September 08, 2007 at 01:51 PM

  • Hey Jonathan,
    One small thing regarding the setVisible() issue.
    Take a look at what Wicket says about isVisible() :

    WARNING: this method can be called multiple times during a request. If you override this method, it is a good idea to keep it cheap in terms of processing. Alternatively, you can call setVisible(boolean).
    BTW, can you give an example with the isDirty() suggestion?

    Thanks

    Posted by: egolan on March 11, 2008 at 07:32 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds