/* * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package javafx.collections; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * Abstract class that serves as a base class for {@link ObservableList} implementations that are modifiable. * * To implement a modifiable {@code ObservableList} class, you just need to implement the following set of methods: * * * and the notifications and built and fired automatically for you. * *

Example of a simple {@code ObservableList} delegating to another {@code List} would look like this: * *

 *
 *   public class ArrayObservableList<E> extends ModifiableObservableList<E> {
 *
 *   private final List<E> delegate = new ArrayList<>();
 *
 *   public E get(int index) {
 *       return delegate.get(index);
 *   }
 *
 *   public int size() {
 *       return delegate.size();
 *   }
 *
 *   protected void doAdd(int index, E element) {
 *       delegate.add(index, element);
 *   }
 *
 *   protected E doSet(int index, E element) {
 *       return delegate.set(index, element);
 *   }
 *
 *   protected E doRemove(int index) {
 *       return delegate.remove(index);
 *   }
 *
 * 
* * @param the type of the elements contained in the List * @see ObservableListBase * @since JavaFX 8.0 */ public abstract class ModifiableObservableListBase extends ObservableListBase { @Override public boolean setAll(Collection col) { beginChange(); try { clear(); addAll(col); } finally { endChange(); } return true; } @Override public boolean addAll(Collection c) { beginChange(); try { boolean res = super.addAll(c); return res; } finally { endChange(); } } @Override public boolean addAll(int index, Collection c) { beginChange(); try { boolean res = super.addAll(index, c); return res; } finally { endChange(); } } @Override protected void removeRange(int fromIndex, int toIndex) { beginChange(); try { super.removeRange(fromIndex, toIndex); } finally { endChange(); } } @Override public boolean removeAll(Collection c) { beginChange(); try { boolean res = super.removeAll(c); return res; } finally { endChange(); } } @Override public boolean retainAll(Collection c) { beginChange(); try { boolean res = super.retainAll(c); return res; } finally { endChange(); } } @Override public void add(int index, E element) { doAdd(index, element); beginChange(); nextAdd(index, index + 1); ++modCount; endChange(); } @Override public E set(int index, E element) { E old = doSet(index, element); beginChange(); nextSet(index, old); endChange(); return old; } @Override public boolean remove(Object o) { int i = indexOf(o); if (i != - 1) { remove(i); return true; } return false; } @Override public E remove(int index) { E old = doRemove(index); beginChange(); nextRemove(index, old); ++modCount; endChange(); return old; } @Override public List subList(int fromIndex, int toIndex) { return new SubObservableList(super.subList(fromIndex, toIndex)); } @Override public abstract E get(int index); @Override public abstract int size(); /** * Adds the {@code element} to the List at the position of {@code index}. * *

For the description of possible exceptions, please refer to the documentation * of {@link #add(java.lang.Object) } method. * * @param index the position where to add the element * @param element the element that will be added * @throws ClassCastException * @throws NullPointerException * @throws IllegalArgumentException * @throws IndexOutOfBoundsException if the index is out of range * (index < 0 || index > size()) */ protected abstract void doAdd(int index, E element); /** * Sets the {@code element} in the List at the position of {@code index}. * *

For the description of possible exceptions, please refer to the documentation * of {@link #set(int, java.lang.Object) } method. * * @param index the position where to set the element * @param element the element that will be set at the specified position * @return the old element at the specified position * * @throws ClassCastException * @throws NullPointerException * @throws IllegalArgumentException * @throws IndexOutOfBoundsException if the index is out of range * (index < 0 || index >= size()) */ protected abstract E doSet(int index, E element); /** * Removes the element at position of {@code index}. * * @param index the index of the removed element * @return the removed element * * @throws IndexOutOfBoundsException if the index is out of range * (index < 0 || index >= size()) */ protected abstract E doRemove(int index); private class SubObservableList implements List { public SubObservableList(List sublist) { this.sublist = sublist; } private List sublist; @Override public int size() { return sublist.size(); } @Override public boolean isEmpty() { return sublist.isEmpty(); } @Override public boolean contains(Object o) { return sublist.contains(o); } @Override public Iterator iterator() { return sublist.iterator(); } @Override public Object[] toArray() { return sublist.toArray(); } @Override public T[] toArray(T[] a) { return sublist.toArray(a); } @Override public boolean add(E e) { return sublist.add(e); } @Override public boolean remove(Object o) { return sublist.remove(o); } @Override public boolean containsAll(Collection c) { return sublist.containsAll(c); } @Override public boolean addAll(Collection c) { beginChange(); try { boolean res = sublist.addAll(c); return res; } finally { endChange(); } } @Override public boolean addAll(int index, Collection c) { beginChange(); try { boolean res = sublist.addAll(index, c); return res; } finally { endChange(); } } @Override public boolean removeAll(Collection c) { beginChange(); try { boolean res = sublist.removeAll(c); return res; } finally { endChange(); } } @Override public boolean retainAll(Collection c) { beginChange(); try { boolean res = sublist.retainAll(c); return res; } finally { endChange(); } } @Override public void clear() { beginChange(); try { sublist.clear(); } finally { endChange(); } } @Override public E get(int index) { return sublist.get(index); } @Override public E set(int index, E element) { return sublist.set(index, element); } @Override public void add(int index, E element) { sublist.add(index, element); } @Override public E remove(int index) { return sublist.remove(index); } @Override public int indexOf(Object o) { return sublist.indexOf(o); } @Override public int lastIndexOf(Object o) { return sublist.lastIndexOf(o); } @Override public ListIterator listIterator() { return sublist.listIterator(); } @Override public ListIterator listIterator(int index) { return sublist.listIterator(index); } @Override public List subList(int fromIndex, int toIndex) { return new SubObservableList(sublist.subList(fromIndex, toIndex)); } @Override public boolean equals(Object obj) { return sublist.equals(obj); } @Override public int hashCode() { return sublist.hashCode(); } @Override public String toString() { return sublist.toString(); } } }