1 11 package org.eclipse.jface.internal.databinding.internal.observable; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.jface.internal.databinding.provisional.DataBindingContext; 17 import org.eclipse.jface.internal.databinding.provisional.description.Property; 18 import org.eclipse.jface.internal.databinding.provisional.observable.Diffs; 19 import org.eclipse.jface.internal.databinding.provisional.observable.list.IListChangeListener; 20 import org.eclipse.jface.internal.databinding.provisional.observable.list.IObservableList; 21 import org.eclipse.jface.internal.databinding.provisional.observable.list.ListDiff; 22 import org.eclipse.jface.internal.databinding.provisional.observable.list.ObservableList; 23 import org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue; 24 import org.eclipse.jface.internal.databinding.provisional.observable.value.IValueChangeListener; 25 import org.eclipse.jface.internal.databinding.provisional.observable.value.ValueDiff; 26 import org.eclipse.jface.util.Assert; 27 28 32 public class NestedObservableList extends ObservableList { 33 34 private boolean updating = false; 35 36 private IListChangeListener innerChangeListener = new IListChangeListener() { 37 public void handleListChange(IObservableList source, ListDiff diff) { 38 if (!updating) { 39 fireListChange(diff); 40 } 41 } 42 }; 43 44 private Object currentOuterValue; 45 46 private Object feature; 47 48 private IObservableList innerObservableList; 49 50 private DataBindingContext databindingContext; 51 52 private IObservableValue outerObservableValue; 53 54 60 public NestedObservableList(DataBindingContext databindingContext, 61 IObservableValue outerObservableValue, Object feature, 62 Class featureType) { 63 super(new ArrayList (), featureType); 64 this.databindingContext = databindingContext; 65 this.feature = feature; 66 this.outerObservableValue = outerObservableValue; 67 updateInnerObservableValue(outerObservableValue); 68 69 outerObservableValue.addValueChangeListener(outerChangeListener); 70 } 71 72 IValueChangeListener outerChangeListener = new IValueChangeListener() { 73 public void handleValueChange(IObservableValue source, ValueDiff diff) { 74 List oldList = new ArrayList (wrappedList); 75 updateInnerObservableValue(outerObservableValue); 76 fireListChange(Diffs.computeListDiff(oldList, wrappedList)); 77 } 78 }; 79 80 private void updateInnerObservableValue( 81 IObservableValue outerObservableValue) { 82 currentOuterValue = outerObservableValue.getValue(); 83 if (innerObservableList != null) { 84 innerObservableList.removeListChangeListener(innerChangeListener); 85 innerObservableList.dispose(); 86 } 87 if (currentOuterValue == null) { 88 innerObservableList = null; 89 wrappedList = new ArrayList (); 90 } else { 91 this.innerObservableList = (IObservableList) databindingContext 92 .createObservable(new Property(currentOuterValue, feature, 93 (Class ) getElementType(), Boolean.TRUE)); 94 wrappedList = innerObservableList; 95 Object innerValueType = innerObservableList.getElementType(); 96 Assert.isTrue(getElementType().equals(innerValueType), 97 "Cannot change value type in a nested updatable value"); innerObservableList.addListChangeListener(innerChangeListener); 99 } 100 } 101 102 public void dispose() { 103 super.dispose(); 104 105 if (outerObservableValue != null) { 106 outerObservableValue.removeValueChangeListener(outerChangeListener); 107 outerObservableValue.dispose(); 108 } 109 if (innerObservableList != null) { 110 innerObservableList.removeListChangeListener(innerChangeListener); 111 innerObservableList.dispose(); 112 } 113 currentOuterValue = null; 114 databindingContext = null; 115 feature = null; 116 innerObservableList = null; 117 innerChangeListener = null; 118 } 119 120 } 121 | Popular Tags |