Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

プレゼン、ボランティアコーチします!

勉強会でスピーカーをやりたいけど、プレゼンが初めて、苦手という方に無償でコーチします!資料レビューや録画リハへアドバイスします。Twitter@jyukutyoまでメンションでもDMでも。

私はデブサミやJJUG CCCなど200人規模で登壇経験ありです。海外での登壇も短いながらあり。デブサミ2017では公募スピーカー1位でした!

Introducing Apache Wicketの超意訳(9)

http://www.theserverside.com/tt/articles/article.tss?l=IntroducingApacheWicket

After calling super(id), the SearchPanel adds the SearchForm (implemented as a private class).
Let's look at the form class next.

super(id)を呼び出したあと、SearchPanelに(privateなクラスとして実装した)SearchFormを追加します。
次にフォームクラスを見てみましょう。

private class SearchForm extends Form {

        private String searchString;

        public SearchForm(String id) {
            super(id);

            add(new TextField("searchString",
                  new PropertyModel(this, "searchString")));
            add(new BookmarkablePageLink("addContact",
                  EditContact.class));
            setMarkupId("search-form");
        }

        public void onSubmit() {
            PageParameters params = new PageParameters();
            params.add("q", getSearchString());
            setResponsePage(ListContacts.class, params);
        }

        public String getSearchString() {
            return searchString;
        }

        public void setSearchString(String searchString) {
            this.searchString = searchString;
        }
    }

The SearchForm extends another Wicket component: Form.
Forms are components that contain other components, like TextFields, TextAreas or DropDownChoices.
However, Forms aren't limited to what they can contain.
You can just as easily add a Panel to a Form as you can to a Page.


In the above form object, I've added a TextField with a component ID of searchString.
The TextField uses a PropertyModel to update the form's searchString property:

SearchFormはもう1つのWicketコンポーネントであるFormを継承します。
FormはTextFieldやTextArea、DropDownChoiceのようなほかのコンポーネントを含んだコンポーネントです。
しかしながら、Formには含むことができるものに制限がありません。
PageにできたようにFormにPanelを簡単に追加できます。


上記のフォームオブジェクトではsearchStringというコンポーネントIDとともにTextFieldを追加しました。
TextFieldはフォームのsearchStringプロパティを更新するためにPropertyModelを使います。

add(new TextField("searchString",
        new PropertyModel(this, "searchString")))

When the search form is submitted, the TextField updates the form's searchString property with the value inserted by the user.
The PropertyModel isn't limited to updating only properties in the form object - it can update object properties in POJOs or other models.
We'll see more examples of PropertyModel in the following sections.


After adding the TextField, a link to the EditContact class is added to the panel.
The link added is a special link called a BookmarkablePageLink.
BookmarkablePageLinks are just that - able to be bookmarked by users.
Bookmarkable links don't have any state, meaning they don't have to know anything about previous requests the user made or where they came from.


Once the components are added to the form, we need to tell the form what to do when its submitted.
Wicket forms have a default submit listener useful when the form only has one submit button:

検索フォームをサブミットしたとき、TextFieldはユーザが入力した値でフォームのsearchStringプロパティを更新します。
PropertyModelはフォームオブジェクトのプロパティだけを更新するような制限があるわけではありません。POJOやほかのモデルのオブジェクトでもプロパティを更新できます。
以下のセクションでPropertyModelの例をもっと見ていきましょう。


TextFieldを追加したあと、EditContactクラスへのリンクをパネルに追加します。
追加したリンクはBookmarkablePageLinkと呼ぶ特別なリンクです。
BookmarkablePageLinkはユーザがブックマークできます。
ブックマーク可能なリンクは状態をまったく持ちません。それが意味することは、ユーザが前に作成したリクエストやどこから北リクエストなのかをリンクはまったく知る必要がないということです。


一度コンポーネントをフォームに追加すれば、それをサブミットしたときに何をするべきかフォームに伝える必要があります。
Wicketのフォームにはフォームが1つしかサブミットボタンを持っていないときに役に立つデフォルトのサブミットリスナーがあります。

    public void onSubmit() {
        PageParameters params = new PageParameters();
        params.add("q", getSearchString());
        setResponsePage(ListContacts.class, params);
    }

The onSubmit listener is called after all form components are validated and model objects are updated.
In the above implementation, the form submits the searchString to the ListContacts class using the PageParameters object.
PageParameters is a simple object used to encapsulate URL query parameters.
Finally, the setResponsePage(Class, PageParameters) method is called, setting ListContacts as the page responding to the user's request.


With the SearchPanel class created, let's look at the markup:

onSubmitリスナーはフォームのコンポーネントがすべて検証されモデルオブジェクトが更新されたあとに呼び出されます。
上記の実装では、フォームはPageParametersオブジェクトを使ってListContactsクラスにsearchStringをサブミットします。
PageParametersはURLのクエリパラメータをカプセル化するために使う単純なオブジェクトです。
最後にsetResponsePage(Class, PageParameters)メソッドを呼び出して、ユーザのリクエストに応答するためにページとしてListContactsを設定します。


SearchPanelクラスを作成したので、マークアップを見てみましょう。

<wicket:panel>
<form wicket:id="searchForm">
    <table>
        <tr>
            <td>Search</td>
            <td>
                <input wicket:id="searchString" type="text" name="search"/>
            </td>
            <td><input type="submit" value="Go" class="button"></td>
            <td><a wicket:id="addContact" href="#">Add New Contact</a></td>
        </tr>
    </table>
</form>
</wicket:panel>

Our panel markup is pretty simple and has the same structure as the SearchPanel class.
The form component contains the TextField and BookmarkablePageLink compoents.
We didn't need to create a special component for the submit button since we're using the form's default submit behavior.
We'll see an example later where we're using two submit buttons.

パネルのマークアップはとても単純で、SearchPanelクラスと同じ構造です。
フォームのコンポーネントはTextFieldとBookmarkablePageLinkコンポーネントを含みます。
フォームにあるデフォルトのサブミットの振る舞いを使うので、サブミットボタンに対する特別なコンポーネントを作成する必要はありません。
2つのサブミットボタンを使う例は後ほど紹介します。