svnno****@sourc*****
svnno****@sourc*****
2009年 1月 3日 (土) 12:56:16 JST
Revision: 2351 http://svn.sourceforge.jp/view?root=jiemamy&view=rev&rev=2351 Author: shin1 Date: 2009-01-03 12:56:16 +0900 (Sat, 03 Jan 2009) Log Message: ----------- j-eventの試験が通っていなかった時に発見した問題点を修正。 clear()時に要素の監視が止まっていなかった。 Map,Setに関してはChangeSupportに対応できていなかった。 Modified Paths: -------------- artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableList.java artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableMap.java artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableSet.java artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableListTest.java artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableMapTest.java -------------- next part -------------- Modified: artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableList.java =================================================================== --- artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableList.java 2009-01-02 14:21:10 UTC (rev 2350) +++ artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableList.java 2009-01-03 03:56:16 UTC (rev 2351) @@ -135,9 +135,10 @@ */ @Override public boolean addAll(int index, Collection<? extends T> collection) { + int i = index; if (collection != null && collection.size() > 0) { for (T element : collection) { - add(index++, element); + add(i++, element); } return true; } else { @@ -176,6 +177,8 @@ T element = iterator.next(); fireChange(new ObservableCollectionChangeEvent<List<T>, T>( ObservableCollectionChangeEvent.Timing.AFTER_REMOVE, this, index, element)); + // 要素に対する監視をやめる。 + endObserve(element); index++; } removedList.clear(); // 用済みなので破棄する。 @@ -409,12 +412,12 @@ if (element instanceof Adaptable) { ModelChangeSupport changeSupport = ((Adaptable) element).getAdapter(ModelChangeSupport.class); if (changeSupport != null) { - // バブリング用のListenerを追加する。 + // バブリング用のListenerを削除する。 changeSupport.removeModelChangeListener(modelChangeListener); } else { Observable observable = ((Adaptable) element).getAdapter(Observable.class); if (observable != null) { - // 通常のListenerを追加する。 + // 通常のListenerを削除する。 observable.removeModelChangeListener(modelChangeListener); } } Modified: artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableMap.java =================================================================== --- artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableMap.java 2009-01-02 14:21:10 UTC (rev 2350) +++ artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableMap.java 2009-01-03 03:56:16 UTC (rev 2351) @@ -29,6 +29,7 @@ import org.jiemamy.event.ModelChangeEvent; import org.jiemamy.event.ModelChangeListener; +import org.jiemamy.event.ModelChangeSupport; import org.jiemamy.event.Observable; import org.jiemamy.event.ObservableCollectionChangeEvent; import org.jiemamy.event.ObservableCollectionChangeListener; @@ -110,10 +111,8 @@ for (V value : removedList) { fireChange(new ObservableCollectionChangeEvent<Map<K, V>, V>( ObservableCollectionChangeEvent.Timing.AFTER_REMOVE, this, index++, value)); - Observable observable = getObservableAdapter(value); - if (observable != null) { - observable.removeModelChangeListener(modelChangeListener); - } + // 要素に対する監視をやめる。 + endObserve(value); } removedList.clear(); } @@ -168,10 +167,8 @@ fireChange(new ObservableCollectionChangeEvent<Map<K, V>, V>(ObservableCollectionChangeEvent.Timing.BEFORE_ADD, this, index, value)); V result = map.put(key, value); - Observable observable = getObservableAdapter(value); - if (observable != null) { - observable.addModelChangeListener(modelChangeListener); - } + // 要素に対する監視を開始する。 + startObserve(value); fireChange(new ObservableCollectionChangeEvent<Map<K, V>, V>(ObservableCollectionChangeEvent.Timing.AFTER_ADD, this, index, value)); return result; @@ -200,10 +197,9 @@ V result = map.remove(key); fireChange(new ObservableCollectionChangeEvent<Map<K, V>, V>( ObservableCollectionChangeEvent.Timing.AFTER_REMOVE, this, index, result)); - Observable observable = getObservableAdapter(result); - if (observable != null) { - observable.removeModelChangeListener(modelChangeListener); - } + // 要素に対する監視をやめる。 + endObserve(result); + return result; } @@ -230,6 +226,26 @@ } /** + * 監視可能な要素だった場合は監視をやめる。 + * @param element + */ + private void endObserve(V element) { + if (element instanceof Adaptable) { + ModelChangeSupport changeSupport = ((Adaptable) element).getAdapter(ModelChangeSupport.class); + if (changeSupport != null) { + // バブリング用のListenerを削除する。 + changeSupport.removeModelChangeListener(modelChangeListener); + } else { + Observable observable = ((Adaptable) element).getAdapter(Observable.class); + if (observable != null) { + // 通常のListenerを削除する。 + observable.removeModelChangeListener(modelChangeListener); + } + } + } + } + + /** * 全てのObserver({@link #listeners})に対してEventを通知する。 * THINK かなり内部的なclassなので、このclassのfireChange()はprivateでも良いのではないか? * @param event @@ -241,15 +257,22 @@ } /** - * valueが{@link Observable}の実装を持っていれば、そのインタスンスを返す。 - * @param value - * @return valueが{@link Observable}の実装を持っていない場合はnullを返す。 + * 監視可能な要素だった場合は監視を開始する。 + * @param element */ - private Observable getObservableAdapter(V value) { - if (value instanceof Adaptable) { - return ((Adaptable) value).getAdapter(Observable.class); - } else { - return null; + private void startObserve(V element) { + if (element instanceof Adaptable) { + ModelChangeSupport changeSupport = ((Adaptable) element).getAdapter(ModelChangeSupport.class); + if (changeSupport != null) { + // バブリング用のListenerを追加する。 + changeSupport.addModelChangeListener(modelChangeListener); + } else { + Observable observable = ((Adaptable) element).getAdapter(Observable.class); + if (observable != null) { + // 通常のListenerを追加する。 + observable.addModelChangeListener(modelChangeListener); + } + } } } @@ -290,5 +313,4 @@ ObservableCollectionChangeEvent.Timing.COLLECTION_CHANGED, list, index, source)); } } - } Modified: artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableSet.java =================================================================== --- artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableSet.java 2009-01-02 14:21:10 UTC (rev 2350) +++ artemis/trunk/org.jiemamy.event/src/main/java/org/jiemamy/utils/ObservableSet.java 2009-01-03 03:56:16 UTC (rev 2351) @@ -29,6 +29,7 @@ import org.jiemamy.event.ModelChangeEvent; import org.jiemamy.event.ModelChangeListener; +import org.jiemamy.event.ModelChangeSupport; import org.jiemamy.event.Observable; import org.jiemamy.event.ObservableCollectionChangeEvent; import org.jiemamy.event.ObservableCollectionChangeListener; @@ -91,12 +92,9 @@ int index = -1; fireChange(new ObservableCollectionChangeEvent<Set<T>, T>(ObservableCollectionChangeEvent.Timing.BEFORE_ADD, this, index, o)); + boolean result = set.add(o); // 要素に対する監視を開始する。 - boolean result = set.add(o); - Observable observable = getObservableAdapter(o); - if (observable != null) { - observable.addModelChangeListener(modelChangeListener); - } + startObserve(o); fireChange(new ObservableCollectionChangeEvent<Set<T>, T>(ObservableCollectionChangeEvent.Timing.AFTER_ADD, this, index, o)); return result; @@ -146,6 +144,8 @@ T element = iterator.next(); fireChange(new ObservableCollectionChangeEvent<Set<T>, T>( ObservableCollectionChangeEvent.Timing.AFTER_REMOVE, this, index, element)); + // 要素に対する監視をやめる。 + endObserve(element); index++; } removedList.clear(); // 用済みなので破棄する。 @@ -191,10 +191,7 @@ this, index, t)); boolean result = set.remove(t); // 要素に対する監視をやめる。 - Observable observable = getObservableAdapter(t); - if (observable != null) { - observable.removeModelChangeListener(modelChangeListener); - } + endObserve(t); fireChange(new ObservableCollectionChangeEvent<Set<T>, T>(ObservableCollectionChangeEvent.Timing.AFTER_REMOVE, this, index, t)); return result; @@ -268,6 +265,26 @@ } /** + * 監視可能な要素だった場合は監視をやめる。 + * @param element + */ + private void endObserve(T element) { + if (element instanceof Adaptable) { + ModelChangeSupport changeSupport = ((Adaptable) element).getAdapter(ModelChangeSupport.class); + if (changeSupport != null) { + // バブリング用のListenerを削除する。 + changeSupport.removeModelChangeListener(modelChangeListener); + } else { + Observable observable = ((Adaptable) element).getAdapter(Observable.class); + if (observable != null) { + // 通常のListenerを削除する。 + observable.removeModelChangeListener(modelChangeListener); + } + } + } + } + + /** * 全てのObserver({@link #listeners})に対してEventを通知する。 * @param event */ @@ -278,15 +295,22 @@ } /** - * valueが{@link Observable}の実装を持っていれば、そのインタスンスを返す。 - * @param value - * @return valueが{@link Observable}の実装を持っていない場合はnullを返す。 + * 監視可能な要素だった場合は監視を開始する。 + * @param element */ - private Observable getObservableAdapter(T value) { - if (value instanceof Adaptable) { - return ((Adaptable) value).getAdapter(Observable.class); - } else { - return null; + private void startObserve(T element) { + if (element instanceof Adaptable) { + ModelChangeSupport changeSupport = ((Adaptable) element).getAdapter(ModelChangeSupport.class); + if (changeSupport != null) { + // バブリング用のListenerを追加する。 + changeSupport.addModelChangeListener(modelChangeListener); + } else { + Observable observable = ((Adaptable) element).getAdapter(Observable.class); + if (observable != null) { + // 通常のListenerを追加する。 + observable.addModelChangeListener(modelChangeListener); + } + } } } Modified: artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableListTest.java =================================================================== --- artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableListTest.java 2009-01-02 14:21:10 UTC (rev 2350) +++ artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableListTest.java 2009-01-03 03:56:16 UTC (rev 2351) @@ -302,6 +302,12 @@ assertThat(listener.events.get(3).getModel(), is(sameInstance(columns[0]))); assertThat(listener.events.get(4).getModel(), is(sameInstance(columns[1]))); assertThat(listener.events.get(5).getModel(), is(sameInstance(columns[2]))); + + listener.events.clear(); + columns[1].setFreeString("free string"); + columns[2].setFreeString("free string"); + + assertThat("Collectionに残っていない要素に対する属性の変更のEventは通知されない。", listener.events.size(), is(0)); } Modified: artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableMapTest.java =================================================================== --- artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableMapTest.java 2009-01-02 14:21:10 UTC (rev 2350) +++ artemis/trunk/org.jiemamy.event/src/test/java/org/jiemamy/util/ObservableMapTest.java 2009-01-03 03:56:16 UTC (rev 2351) @@ -225,6 +225,12 @@ assertThat("要素の数分まとめてbeforeRemoveが発生する。", listener.events.get(3).getIndex(), is(0)); assertThat("要素の数分まとめてbeforeRemoveが発生する。", listener.events.get(4).getIndex(), is(1)); assertThat("要素の数分まとめてbeforeRemoveが発生する。", listener.events.get(5).getIndex(), is(2)); + + listener.events.clear(); + columns[1].setFreeString("free string"); + columns[2].setFreeString("free string"); + + assertThat("Collectionに残っていない要素に対する属性の変更のEventは通知されない。", listener.events.size(), is(0)); }