[Seasar-user:2615] Re: [S2JSF]同じページを繰り返し表示する場合の戻るボタンの動作について
Sea Slug
seaslug
2005年 9月 27日 (火) 17:21:45 JST
竹田です。長々とすみません。これが最後です。
2. サーバ側のforeachに関連付けられたリスト変数をsessionに保存されたviewとク
ライアントからポストされた内容から再構成するようにする。
の具体的方法について説明します。
- まず、次のコレクションを継承したインターフェースとその実装を追加します。
public interface RestorableCollection extends Collection {
public Class getElementClass();
}
public class RestorableArrayList extends ArrayList implements
RestorableCollection {
private Class c;
public Class getElementClass() {
return c;
}
public RestorableArrayList(int initialCapacity) {
super(initialCapacity);
// TODO 自動生成されたコンストラクター・スタブ
}
public RestorableArrayList(Collection collection) {
super(collection);
if (! collection.isEmpty()){
c = collection.iterator().next().getClass();
}
}
public void add(int index, Object element) {
typeCheck(element);
super.add(index, element);
}
public boolean add(Object o) {
typeCheck(o);
return super.add(o);
}
public boolean addAll(Collection c) {
for (Iterator it = c.iterator(); it.hasNext();){
typeCheck(it.next());
}
return super.addAll(c);
}
public boolean addAll(int index, Collection c) {
for (Iterator it = c.iterator(); it.hasNext();){
typeCheck(it.next());
}
return super.addAll(index, c);
}
public Object set(int index, Object element) {
typeCheck(element);
return super.set(index, element);
}
private void typeCheck(Object element){
if (c == null){
c = element.getClass();
} else {
if (!c.isInstance(element)){
throw new IllegalStateException("Irregular element
collection");
}
}
}
}
- 次にorg.seasar.jsf.component.ForEach#setupRowsを次のように変更します。
protected void setupRows() {
Object items =
BindingUtil.getBindingValue(this,JsfConstants.ITEMS_ATTR);
if (items == null) {
rows = new Object[rowCount];
} else if (items instanceof RestorableCollection){
RestorableCollection collections = (RestorableCollection)items;
if (collections.getElementClass() == null){
rows = new Object[0];
} else {
rows =
(Object[])Array.newInstance(collections.getElementClass(), rowCount);
collections.clear();
for (int i = 0 ; i < rows.length ; ++i){
try {
rows[i] =
collections.getElementClass().newInstance();
collections.add(rows[i]);
} catch (InstantiationException e) {
throw new
InstantiationError(e.getLocalizedMessage());
} catch (IllegalAccessException e) {
throw new
IllegalAccessError(e.getLocalizedMessage());
}
}
}
} else if (items instanceof Collection) {
rows = new ArrayList((Collection) items).toArray();
} else if (items.getClass().isArray()) {
rows = (Object[]) items;
} else {
throw new IllegalStateException(JsfConstants.ITEMS_ATTR);
}
}
つまり、foreachに関連付けられているリスト変数がRestorableCollection のイ
ンスタンスである場合のみ、サーバ側で保持している情報をいったんクリアして、
viewに保持されている個数分だけ新たに用意します。後はUpdateModelValuesでポス
トされた内容が格納されますので、以降は内容を参照することができるようになりま
す。
ただし、ポストされない内容は更新されないのでforeachに関連付けられているリ
スト変数の要素のすべての内容が復元されるわけではありません。必要な情報は
hiddenタグを使うなどして必ずポストされるようにする必要があります。
リスト変数をRestorableCollectionのインスタンスにしなければ、今までどおりク
ライアント側の状態で上書きされることはありません。
foreach2のサンプルで実験する場合には、foreach2.diconでforEach2DtoListのク
ラスをRestorableArrayListにすれば大丈夫です。
以上、長々とすみませんでした。
_________________________________________________________________
ウィルス駆除も無料の 「MSN Hotmail」 http://www.hotmail.com/
Seasar-user メーリングリストの案内