レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

Wicket Examples ■GuestBook Application

WicketのGuestBookサンプルのチュートリアル

GuestBook
The GuestBook application allows users to enter comments that appear on a page like a weblog.
Drawing the list of comments is very easy with the Wicket ListView component.
This example also gives an impression of what form handling is like.

このGuestBookアプリケーションでは、ブログに似たコメントの入力ができます。
コメントのリストを表示するのは、Wicketリストビューコンポーネントを使えばとても簡単です。
またこのサンプルは、フォームの処理に似ているという印象があります。


As with all examples, you have to put all files in the same package directory.
This means putting the markup files and the java files next to one another. It is possible to alter this behavior, but that is beyond the scope of this example.

すべてのサンプルは、同じパッケージディレクトリにおいてください。
つまり、マークアップ(HTML)ファイルとJavaファイルを隣合うようにおきます。
(HTMLの配置は)他にも方法はありますが、それを説明するのはこのサンプルの範囲外です。




Comment.java
The Comment POJO model is very straightforward (we have omitted the getter/setter code for brevity in this example):


Comment.java
コメントのPOJOモデルは、とても簡単です。(このサンプルでは簡潔に表すためにgetter/setterのコードは省略しています。)

package wicket.examples.guestbook;

import java.io.Serializable;
import java.util.Date;

public class Comment implements Serializable
{
    public String text;
    public Date date = new Date();
}


GuestBook.java
In the file GuestBook.java we have put the Java component code for the guestbook page.
This is the homepage for the guestbook application. The page consists of a form for entering new items to the guestbook and a list of repeating markup for showing the guestbook entries.


GuestBook.java
この「GuestBook.java」ファイルでは、GuestBookページのためのJavaコンポーネントコード作成します。
このページはGuestBookアプリケーションのホームページです。
このページは、ゲストブックのための新しいアイテムを入力するフォームと、ゲストブックの入力を繰り返し表示するリストからなります。

The GuestBook constructor adds a CommentForm and a ListView of the comments.
Notice how the model is passed in as the second argument to the ListView constructor.

ゲストブックのコンストラクターは、コメントフォーム(CommentForm)とコメントのリストビューを追加します。
第2引数でリストビューのコンストラクタに対してどのようにモデルが渡されるかに注意してください。

Then as the view renders, the populateItem method is called passing in a ListItem container for the current row in the list.

画面が表示されたとき、リストの現在行でListItemコンテナのpopulateItemメソッドが呼ばれます。

The implementation below obtains the Comment POJO from the list item and adds label components for the date and text of the Comment.
This is all accomplished in just a few lines of code.

以下の実装は、コメントPOJOをリストアイテムから取得し、データとコメントのテキストのためのラベルコンポーネントを追加しています。
これは、以下のたった数行のコードですべて完了します。

package wicket.examples.guestbook;

import java.util.Date;
import java.util.List;
import java.util.Vector;

import wicket.markup.html.WebPage;
import wicket.markup.html.basic.Label;
import wicket.markup.html.basic.MultiLineLabel;
import wicket.markup.html.form.Form;
import wicket.markup.html.form.TextArea;
import wicket.markup.html.list.ListItem;
import wicket.markup.html.list.ListView;
import wicket.model.PropertyModel;

public final class GuestBook extends WebPage
{
    /** Use a Vector, as it is synchronized. */
    private static final List commentList = new Vector();
    private final ListView commentListView;

    public GuestBook()
    {
        add(new CommentForm("commentForm"));
        add(commentListView = new ListView("comments", commentList)
        {
            public void populateItem(final ListItem listItem)
            {
                final Comment comment = (Comment)listItem.getModelObject();
                listItem.add(new Label("date", comment.date.toString()));
                listItem.add(new MultiLineLabel("text", comment.text));
            }
        });
    }

    public final class CommentForm extends Form
    {
        private final Comment comment = new Comment();

        public CommentForm(final String componentName)
        {
            super(componentName);
            add(new TextArea("text", new PropertyModel(comment, "text")));
        }

        public final void onSubmit()
        {
            final Comment newComment = new Comment();
            newComment.text = comment.text;

            commentList.add(0, newComment);
            commentListView.modelChanged();

            comment.text = "";
        }
    }
}

When the CommentForm is submitted, the onSubmit() method is called.
Notice that nothing gets the value of the TextArea that was added in the CommentForm constructor.
This is because the comment is the model and the third parameter to the TextArea constructor specified the property of the model to update.
So all onSubmit() has to do is create a new comment from the model that was updated and add it to the comment list.
When the page redraws, the new list will be rendered.

コメントフォーム(CommentForm)がサブミットされたとき、onSubmitメソッドが呼び出されます。
CommentFormコンストラクタに追加されたテキストエリアの値は、何も帰らないことに注意してください。
これは「コメント」が「モデル」であり、TextAreaコンストラクタへの3番目のパラメタはアップデートするモデルのプロパティを指定しているからです。
そのため、すべてのonSubmitメソッドはコメントリストにアップデートや追加されたモデルから新しいコメントを作成する必要があります。
ページが再表示されたとき、新しいリストが描画されます。

We use a Vector as our shared static model used by commentListView (commentList) to ensure that it is only updated by one thread at a time. Remember, this is a multi-user application with a shared model!


1度に1つのスレッドによる更新処理だけであることを保障するために、
commentListView (commentList)によって使われている共有の静的モデルとして、ベクターを使います。
これは複数ユーザーでモデルを共有するアプリケーションです。

Finally, you may notice the call to commentListView.modelChanged().
This informs the list view that its model has been modified.
In more advanced usage scenarios, this would allow Wicket to expire stale pages accessed with the browser's back button.

最後に、commentListView.modelChangedメソッドの呼出しに気付くかも知れません。
これは内部のモデルが変更されたことをリストビューに知らせます。
より高度な利用方法として、この処理はブラウザの戻るボタンが押されたことで古くなったページをWicketによって捨てさせます  


GuestBook.html
In the HTML below, notice the way that the TextArea component is being nested inside the CommentForm.
Wicket is able to keep everything straight because the Java Component.add() calls have to result in the same nesting structure as the HTML.


GuestBook.html
以下のHTMLでは、テキストエリアコンポーネントがCommentFormの中にネストされる方法をとっていることに気をつけてください、。
JavaのComponent.addメソッドの呼出しは、HTMLと同じネスト構造を持たなくてはならないため、Wicektは全てを連続して保持することができます。

Finally, notice the block. This is simply markup that is there for previewing purposes only.
When the page renders, it is stripped out.

最後に気をつけるのは、<wicket:remove>ブロックです。これは確認表示の目的のためだけの単純なマークアップです。
ページが描画されたときには、これは取り除かれます。

<html>
<body>
  <form wicket:id = "commentForm">
    Add your comment here:
    <p>
    <textarea wicket:id = "text">This is a comment</textarea>
    <p>
    <input type = "submit" value = "Submit"/>
  </form>
  <p>
  <span wicket:id = "comments">
    <p>
        <span wicket:id = "date">1/1/2004</span><br>
        <span wicket:id = "text">Comment text goes here.</span>
    </p>
  </span>
  <wicket:remove>
    <p>
        1/2/2004<br/>
        More comment text here.
    </p>
  </wicket:remove>
</body>
</html>                


GuestBookApplication.java
For completeness, we've included the GuestBookApplication class, and as a final treat the modifications to the web.xml file.


GuestBookApplication.java
完成させるために、GuestBookApplicationクラスを追加しました。また、最後の処置としてweb.xmlを修正します。

package wicket.examples.guestbook;

import wicket.protocol.http.WebApplication;

public class GuestBookApplication extends WebApplication
{
    public GuestBookApplication()
    {
    }
    
    public Class getHomePage()
    {
        return GuestBook.class;
    }
}


web.xml
Add the following two sections (servlet and servlet-mapping) to your web.xml file for running this application.

web.xml
アプリケーションを起動するために、以下の2つのセクション(サーブレットサーブレットマッピング)をweb.xmlに追加してください。

    <servlet>
        <servlet-name>GuestBookApplication</servlet-name>
        <servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
        <init-param>
          <param-name>applicationClassName</param-name>
          <param-value>wicket.examples.guestbook.GuestBookApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>GuestBookApplication</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>