Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.collections;
027
028import java.util.Collection;
029import java.util.Iterator;
030import java.util.List;
031import java.util.ListIterator;
032
033/**
034 * Abstract class that serves as a base class for {@link ObservableList} implementations that are modifiable.
035 *
036 * To implement a modifiable {@code ObservableList} class, you just need to implement the following set of methods:
037 * <ul>
038 * <li> {@link #get(int)  get(int)}
039 * <li> {@link #size() size()}
040 * <li> {@link #doAdd(int, java.lang.Object) doAdd(int, Object)}
041 * <li> {@link #doRemove(int) doRemove(int)}
042 * <li> {@link #doSet(int, java.lang.Object) doSet(int, Object)}
043 * </ul>
044 *
045 * and the notifications and built and fired automatically for you.
046 *
047 * <p>Example of a simple {@code ObservableList} delegating to another {@code List} would look like this:
048 *
049 * <pre>
050 *
051 *   <strong>public class</strong> ArrayObservableList&lt;E&gt; <strong>extends</strong> ModifiableObservableList&lt;E&gt; {
052 *
053 *   <strong>private final List</strong>&lt;E&gt; delegate = new <strong>ArrayList</strong>&lt;&gt;();
054 *
055 *   <strong>public E</strong> get(int index) {
056 *       <strong>return</strong> delegate.get(index);
057 *   }
058 *
059 *   <strong>public int</strong> size() {
060 *       <strong>return</strong> delegate.size();
061 *   }
062 *
063 *   <strong>protected void</strong> doAdd(<strong>int</strong> index, <strong>E</strong> element) {
064 *       delegate.add(index, element);
065 *   }
066 *
067 *   <strong>protected E</strong> doSet(<strong>int</strong> index, <strong>E</strong> element) {
068 *       <strong>return</strong> delegate.set(index, element);
069 *   }
070 *
071 *   <strong>protected E</strong> doRemove(<strong>int</strong> index) {
072 *       <strong>return</strong> delegate.remove(index);
073 *   }
074 *
075 * </pre>
076 *
077 * @param <E> the type of the elements contained in the List
078 * @see ObservableListBase
079 * @since 8.0
080 */
081public abstract class ModifiableObservableListBase<E> extends ObservableListBase<E> {
082
083    @Override
084    public boolean setAll(Collection<? extends E> col) {
085        beginChange();
086        try {
087            clear();
088            addAll(col);
089        } finally {
090            endChange();
091        }
092        return true;
093    }
094
095    @Override
096    public boolean addAll(Collection<? extends E> c) {
097        beginChange();
098        try {
099            boolean res = super.addAll(c);
100            return res;
101        } finally {
102            endChange();
103        }
104    }
105
106    @Override
107    public boolean addAll(int index, Collection<? extends E> c) {
108        beginChange();
109        try {
110            boolean res = super.addAll(index, c);
111            return res;
112        } finally {
113            endChange();
114        }
115    }
116
117    @Override
118    protected void removeRange(int fromIndex, int toIndex) {
119        beginChange();
120        try {
121            super.removeRange(fromIndex, toIndex);
122        } finally {
123            endChange();
124        }
125    }
126
127    @Override
128    public boolean removeAll(Collection<?> c) {
129        beginChange();
130        try {
131            boolean res = super.removeAll(c);
132            return res;
133        } finally {
134            endChange();
135        }
136    }
137
138    @Override
139    public boolean retainAll(Collection<?> c) {
140        beginChange();
141        try {
142            boolean res = super.retainAll(c);
143            return res;
144        } finally {
145            endChange();
146        }
147    }
148
149    @Override
150    public void add(int index, E element) {
151        doAdd(index, element);
152        beginChange();
153        nextAdd(index, index + 1);
154        ++modCount;
155        endChange();
156    }
157
158    @Override
159    public E set(int index, E element) {
160        E old = doSet(index, element);
161        beginChange();
162        nextSet(index, old);
163        endChange();
164        return old;
165    }
166
167    @Override
168    public boolean remove(Object o) {
169        int i = indexOf(o);
170        if (i != - 1) {
171            remove(i);
172            return true;
173        }
174        return false;
175    }
176
177    @Override
178    public E remove(int index) {
179        E old = doRemove(index);
180        beginChange();
181        nextRemove(index, old);
182        ++modCount;
183        endChange();
184        return old;
185    }
186
187    @Override
188    public List<E> subList(int fromIndex, int toIndex) {
189        return new SubObservableList(super.subList(fromIndex, toIndex));
190    }
191
192    @Override
193    public abstract E get(int index);
194
195    @Override
196    public abstract int size();
197
198    /**
199     * Adds the {@code element} to the List at the position of {@code index}.
200     *
201     * <p>For the description of possible exceptions, please refer to the documentation
202     * of {@link #add(java.lang.Object) } method.
203     *
204     * @param index the position where to add the element
205     * @param element the element that will be added
206
207     * @throws ClassCastException
208     * @throws NullPointerException
209     * @throws IllegalArgumentException
210     * @throws IndexOutOfBoundsException if the index is out of range
211     *         (<tt>index &lt; 0 || index &gt; size()</tt>)
212     */
213    protected abstract void doAdd(int index, E element);
214
215    /**
216     * Sets the {@code element} in the List at the position of {@code index}.
217     *
218     * <p>For the description of possible exceptions, please refer to the documentation
219     * of {@link #set(int, java.lang.Object) } method.
220     * 
221     * @param index the position where to set the element
222     * @param element the element that will be set at the specified position
223     * @return the old element at the specified position
224     *
225     * @throws ClassCastException
226     * @throws NullPointerException
227     * @throws IllegalArgumentException
228     * @throws IndexOutOfBoundsException if the index is out of range
229     *         (<tt>index &lt; 0 || index &gt;= size()</tt>)
230     */
231    protected abstract E doSet(int index, E element);
232
233    /**
234     * Removes the element at position of {@code index}.
235     *
236     * @param index the index of the removed element
237     * @return the removed element
238     *
239     * @throws IndexOutOfBoundsException if the index is out of range
240     *         (<tt>index &lt; 0 || index &gt;= size()</tt>)
241     */
242    protected abstract E doRemove(int index);
243
244    private class SubObservableList implements List<E> {
245
246        public SubObservableList(List<E> sublist) {
247            this.sublist = sublist;
248        }
249        private List<E> sublist;
250
251        @Override
252        public int size() {
253            return sublist.size();
254        }
255
256        @Override
257        public boolean isEmpty() {
258            return sublist.isEmpty();
259        }
260
261        @Override
262        public boolean contains(Object o) {
263            return sublist.contains(o);
264        }
265
266        @Override
267        public Iterator<E> iterator() {
268            return sublist.iterator();
269        }
270
271        @Override
272        public Object[] toArray() {
273            return sublist.toArray();
274        }
275
276        @Override
277        public <T> T[] toArray(T[] a) {
278            return sublist.toArray(a);
279        }
280
281        @Override
282        public boolean add(E e) {
283            return sublist.add(e);
284        }
285
286        @Override
287        public boolean remove(Object o) {
288            return sublist.remove(o);
289        }
290
291        @Override
292        public boolean containsAll(Collection<?> c) {
293            return sublist.containsAll(c);
294        }
295
296        @Override
297        public boolean addAll(Collection<? extends E> c) {
298            beginChange();
299            try {
300                boolean res = sublist.addAll(c);
301                return res;
302            } finally {
303                endChange();
304            }
305        }
306
307        @Override
308        public boolean addAll(int index, Collection<? extends E> c) {
309            beginChange();
310            try {
311                boolean res = sublist.addAll(index, c);
312                return res;
313            } finally {
314                endChange();
315            }
316        }
317
318        @Override
319        public boolean removeAll(Collection<?> c) {
320            beginChange();
321            try {
322                boolean res = sublist.removeAll(c);
323                return res;
324            } finally {
325                endChange();
326            }
327        }
328
329        @Override
330        public boolean retainAll(Collection<?> c) {
331            beginChange();
332            try {
333                boolean res = sublist.retainAll(c);
334                return res;
335            } finally {
336                endChange();
337            }
338        }
339
340        @Override
341        public void clear() {
342            beginChange();
343            try {
344                sublist.clear();
345            } finally {
346                endChange();
347            }
348        }
349
350        @Override
351        public E get(int index) {
352            return sublist.get(index);
353        }
354
355        @Override
356        public E set(int index, E element) {
357            return sublist.set(index, element);
358        }
359
360        @Override
361        public void add(int index, E element) {
362            sublist.add(index, element);
363        }
364
365        @Override
366        public E remove(int index) {
367            return sublist.remove(index);
368        }
369
370        @Override
371        public int indexOf(Object o) {
372            return sublist.indexOf(o);
373        }
374
375        @Override
376        public int lastIndexOf(Object o) {
377            return sublist.lastIndexOf(o);
378        }
379
380        @Override
381        public ListIterator<E> listIterator() {
382            return sublist.listIterator();
383        }
384
385        @Override
386        public ListIterator<E> listIterator(int index) {
387            return sublist.listIterator(index);
388        }
389
390        @Override
391        public List<E> subList(int fromIndex, int toIndex) {
392            return new SubObservableList(sublist.subList(fromIndex, toIndex));
393        }
394
395        @Override
396        public boolean equals(Object obj) {
397            return sublist.equals(obj);
398        }
399
400        @Override
401        public int hashCode() {
402            return sublist.hashCode();
403        }
404
405        @Override
406        public String toString() {
407            return sublist.toString();
408        }
409    }
410}