2010年09月06日

vaadinでちょっとはまりました コンポーネントの制御

またしても罠にはまってしまいました。
前回の画面制御に関連して、コンポーネントの持ち方について理解が足りなかったせいで、いくら登録してもコンポーネントが画面に表示されない状態となりました。
どんなことをしていたかと言うと、
 @一種のウィザードのような2ページで遷移する画面を作成
 A2ページ共通で使うコンポーネントとしてキャンセルボタンを用意
 B各ページにキャンセルボタンを登録
上記のようなことをしていました。
ページの制御は前回の方法をとっています。
removeComponent / addComponent を用いて、直接制御を行っています。
2ページに共通するコンポーネントなので、下記のようなコーディングをしてみました。
結果は最初に記述したように、キャンセルボタンが1ページ目に表示されません。
public class SubWindow extends Window {
  private Layout contextLayout;
  private Layout firstPage;
  private Layout secondPage;
  private Button cancelButton;
  ・・・
  public SubWindow() {
    contextLayout = (VerticalLayout) getContent();
    firstPage = createFirstPage();
    secondPage = createSecondPage();
    cancelButton = new Button("キャンセル", new Button.ClickListener() {
      public void buttonClick(ClickEvent event) {
        ((Window) getParent()).removeWindow(getWindow());
      }
    });
    mainWindow.addComponent(firstPage);

    setMainWindow(mainWindow);
  }
  private Layout createFirstPage() {
    VerticalLayout layout = new VerticalLayout();
    Button button = new new Button("次へ", new Button.ClickListener() {
      public void buttonClick(ClickEvent event) {
        ・・・
        switchPage("secondPage");
      }
    });
    layout.addComponent(button);
    layout.addComponent(cancelButton);
    return layout;
  }
  private Layout createSecondPage() {
    VerticalLayout layout = new VerticalLayout();
    Button button = new Button("実行", new Button.ClickListener() {
      public void buttonClick(ClickEvent event) {
        ・・・
        switchPage("firstPage");
      }
    });
    layout.addComponent(button);
    layout.addComponent(cancelButton);
    return layout;
  }
  private void switchPage(String pageName) {
    if ("firstPage".equals(pageName)){
      contextLayout.addComponent(firstPage);
      contextLayout.removeComponent(secondPage);
    } else {
      contextLayout.removeComponent(firstPage);
      contextLayout.addComponent(secondPage);
    }
  }
}

何が原因なのでしょうか?
一見どこにも問題がなさそうに見えるのですが表示をしてくれません。
2ページ目で表示されるので、キャンセルボタンオブジェクトがなくなってしまったわけではないようです。
最初のページではまだ removeComponent() を実行していないので、怪しいのは addComponent() です。
vaadinのソースを調べてみると、コンポーネントオブジェクトは親(コンテナー)を持っており、コンテナー(親)はコンポーネントのリストを保持して制御をしています。
そこで、addComponent() を確認すると、AbstractComponentContainer#addComponent() では、ご丁寧に追加しようとしているコンポーネントの親(コンテナー)から、自分を削除させています。
コンポーネントは1つのコンポーネントにしか所属できないようです。
createFirstPage() でキャンセルボタンは1ページ目に登録されていますが、次の行でcreateSecondPage() が実行され、このメソッドの中でキャンセルボタンを2ページ目に登録を行っています。
この際にキャンセルボタンの親である1ページ目(Layoutコンテナ)のコンポーネントリストから自分を削除し、2ページ目のコンテナに登録をしています。
そのため、1ページ目に表示してくれなかったわけです。
残念ながら、同じようなコンポーネントでもいちいち作成するようにします。
posted by しん at 00:00| Comment(0) | vaadin | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。