comparison org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.d @ 95:6208d4f6a277

Added trees for databinding.beans and observable
author Frank Benoit <benoit@tionex.de>
date Tue, 21 Apr 2009 10:55:51 +0200
parents
children b74ac5dfcc06
comparison
equal deleted inserted replaced
94:1d37a7813832 95:6208d4f6a277
1 /*******************************************************************************
2 * Copyright (c) 2005, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Brad Reynolds - bug 164653
11 * Brad Reynolds - bug 167204
12 * Gautam Saggar - bug 169529
13 * Brad Reynolds - bug 147515
14 * Matthew Hall - bug 208858, 213145
15 *******************************************************************************/
16 package org.eclipse.core.databinding.observable.list;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.List;
22
23 import org.eclipse.core.databinding.observable.Diffs;
24 import org.eclipse.core.databinding.observable.Realm;
25
26 /**
27 * Mutable observable list backed by an ArrayList.
28 *
29 * <p>
30 * This class is thread safe. All state accessing methods must be invoked from
31 * the {@link Realm#isCurrent() current realm}. Methods for adding and removing
32 * listeners may be invoked from any thread.
33 * </p>
34 *
35 * @since 1.0
36 */
37 public class WritableList : ObservableList {
38
39 /**
40 * Creates an empty writable list in the default realm with a
41 * <code>null</code> element type.
42 *
43 */
44 public this() {
45 this(Realm.getDefault());
46 }
47
48 /**
49 * Creates an empty writable list with a <code>null</code> element type.
50 *
51 * @param realm
52 */
53 public this(Realm realm) {
54 this(realm, new ArrayList(), null);
55 }
56
57 /**
58 * Constructs a new instance with the default realm.
59 *
60 * @param toWrap
61 * @param elementType
62 * can be <code>null</code>
63 */
64 public this(List toWrap, Object elementType) {
65 this(Realm.getDefault(), toWrap, elementType);
66 }
67
68 /**
69 * Creates a writable list containing elements of the given type, wrapping
70 * an existing client-supplied list.
71 *
72 * @param realm
73 * @param toWrap
74 * The java.utilList to wrap
75 * @param elementType
76 * can be <code>null</code>
77 */
78 public this(Realm realm, List toWrap, Object elementType) {
79 super(realm, toWrap, elementType);
80 }
81
82 public Object set(int index, Object element) {
83 checkRealm();
84 Object oldElement = wrappedList.set(index, element);
85 fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index,
86 false, oldElement), Diffs.createListDiffEntry(index, true,
87 element)));
88 return oldElement;
89 }
90
91 /**
92 * @since 1.1
93 */
94 public Object move(int oldIndex, int newIndex) {
95 checkRealm();
96 int size = wrappedList.size();
97 if (oldIndex < 0 || oldIndex >= size)
98 throw new IndexOutOfBoundsException(
99 "oldIndex: " + oldIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
100 if (newIndex < 0 || newIndex >= size)
101 throw new IndexOutOfBoundsException(
102 "newIndex: " + newIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
103 if (oldIndex is newIndex)
104 return wrappedList.get(oldIndex);
105 Object element = wrappedList.remove(oldIndex);
106 wrappedList.add(newIndex, element);
107 fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(oldIndex,
108 false, element), Diffs.createListDiffEntry(newIndex, true,
109 element)));
110 return element;
111 }
112
113 public Object remove(int index) {
114 checkRealm();
115 Object oldElement = wrappedList.remove(index);
116 fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index,
117 false, oldElement)));
118 return oldElement;
119 }
120
121 public bool add(Object element) {
122 checkRealm();
123 bool added = wrappedList.add(element);
124 if (added) {
125 fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
126 wrappedList.size() - 1, true, element)));
127 }
128 return added;
129 }
130
131 public void add(int index, Object element) {
132 checkRealm();
133 wrappedList.add(index, element);
134 fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index,
135 true, element)));
136 }
137
138 public bool addAll(Collection c) {
139 checkRealm();
140 ListDiffEntry[] entries = new ListDiffEntry[c.size()];
141 int i = 0;
142 int addIndex = wrappedList.size();
143 for (Iterator it = c.iterator(); it.hasNext();) {
144 Object element = it.next();
145 entries[i++] = Diffs.createListDiffEntry(addIndex++, true, element);
146 }
147 bool added = wrappedList.addAll(c);
148 fireListChange(Diffs.createListDiff(entries));
149 return added;
150 }
151
152 public bool addAll(int index, Collection c) {
153 checkRealm();
154 ListDiffEntry[] entries = new ListDiffEntry[c.size()];
155 int i = 0;
156 int addIndex = index;
157 for (Iterator it = c.iterator(); it.hasNext();) {
158 Object element = it.next();
159 entries[i++] = Diffs.createListDiffEntry(addIndex++, true, element);
160 }
161 bool added = wrappedList.addAll(index, c);
162 fireListChange(Diffs.createListDiff(entries));
163 return added;
164 }
165
166 public bool remove(Object o) {
167 checkRealm();
168 int index = wrappedList.indexOf(o);
169 if (index is -1) {
170 return false;
171 }
172 wrappedList.remove(index);
173 fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index,
174 false, o)));
175 return true;
176 }
177
178 public bool removeAll(Collection c) {
179 checkRealm();
180 List entries = new ArrayList();
181 for (Iterator it = c.iterator(); it.hasNext();) {
182 Object element = it.next();
183 int removeIndex = wrappedList.indexOf(element);
184 if (removeIndex !is -1) {
185 wrappedList.remove(removeIndex);
186 entries.add(Diffs.createListDiffEntry(removeIndex, false,
187 element));
188 }
189 }
190 if (entries.size() > 0)
191 fireListChange(Diffs.createListDiff(cast(ListDiffEntry[]) entries
192 .toArray(new ListDiffEntry[entries.size()])));
193 return entries.size() > 0;
194 }
195
196 public bool retainAll(Collection c) {
197 checkRealm();
198 List entries = new ArrayList();
199 int removeIndex = 0;
200 for (Iterator it = wrappedList.iterator(); it.hasNext();) {
201 Object element = it.next();
202 if (!c.contains(element)) {
203 entries.add(Diffs.createListDiffEntry(removeIndex, false,
204 element));
205 it.remove();
206 } else {
207 // only increment if we haven't removed the current element
208 removeIndex++;
209 }
210 }
211 if (entries.size() > 0)
212 fireListChange(Diffs.createListDiff(cast(ListDiffEntry[]) entries
213 .toArray(new ListDiffEntry[entries.size()])));
214 return entries.size() > 0;
215 }
216
217 public void clear() {
218 checkRealm();
219 List entries = new ArrayList();
220 for (Iterator it = wrappedList.iterator(); it.hasNext();) {
221 Object element = it.next();
222 // always report 0 as the remove index
223 entries.add(Diffs.createListDiffEntry(0, false, element));
224 it.remove();
225 }
226 fireListChange(Diffs.createListDiff(cast(ListDiffEntry[]) entries
227 .toArray(new ListDiffEntry[entries.size()])));
228 }
229
230 /**
231 * @param elementType
232 * can be <code>null</code>
233 * @return new list with the default realm.
234 */
235 public static WritableList withElementType(Object elementType) {
236 return new WritableList(Realm.getDefault(), new ArrayList(),
237 elementType);
238 }
239 }