/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package com.sun.javafx.collections;
import java.util.
Collection;
import java.util.
Comparator;
import java.util.
Iterator;
import java.util.
List;
import java.util.
ListIterator;
import java.util.
NoSuchElementException;
import javafx.beans.
InvalidationListener;
import javafx.beans.
Observable;
import javafx.collections.
ModifiableObservableListBase;
import javafx.collections.
ObservableList;
import javafx.util.
Callback;
public final class
ObservableSequentialListWrapper<E> extends
ModifiableObservableListBase<E> implements
ObservableList<E>,
SortableList<E>{
private final
List<E>
backingList;
private final
ElementObserver elementObserver;
private
SortHelper helper;
public
ObservableSequentialListWrapper(
List<E>
list) {
backingList =
list;
elementObserver = null;
}
public
ObservableSequentialListWrapper(
List<E>
list,
Callback<E,
Observable[]>
extractor) {
backingList =
list;
this.
elementObserver = new
ElementObserver(
extractor, new
Callback<E,
InvalidationListener>() {
@
Override
public
InvalidationListener call(final E
e) {
return new
InvalidationListener() {
@
Override
public void
invalidated(
Observable observable) {
beginChange();
int
i = 0;
for (
Iterator<?>
it =
backingList.
iterator();
it.
hasNext();) {
if (
it.
next() ==
e) {
nextUpdate(
i);
}
++
i;
}
endChange();
}
};
}
}, this);
for (E
e :
backingList) {
elementObserver.
attachListener(
e);
}
}
@
Override
public boolean
contains(
Object o) {
return
backingList.
contains(
o);
}
@
Override
public boolean
containsAll(
Collection<?>
c) {
return
backingList.
containsAll(
c);
}
@
Override
public int
indexOf(
Object o) {
return
backingList.
indexOf(
o);
}
@
Override
public int
lastIndexOf(
Object o) {
return
backingList.
lastIndexOf(
o);
}
@
Override
public
ListIterator<E>
listIterator(final int
index) {
return new
ListIterator<E>() {
private final
ListIterator<E>
backingIt =
backingList.
listIterator(
index);
private E
lastReturned;
@
Override
public boolean
hasNext() {
return
backingIt.
hasNext();
}
@
Override
public E
next() {
return
lastReturned =
backingIt.
next();
}
@
Override
public boolean
hasPrevious() {
return
backingIt.
hasPrevious();
}
@
Override
public E
previous() {
return
lastReturned =
backingIt.
previous();
}
@
Override
public int
nextIndex() {
return
backingIt.
nextIndex();
}
@
Override
public int
previousIndex() {
return
backingIt.
previousIndex();
}
@
Override
public void
remove() {
beginChange();
int
idx =
previousIndex();
backingIt.
remove();
nextRemove(
idx,
lastReturned);
endChange();
}
@
Override
public void
set(E
e) {
beginChange();
int
idx =
previousIndex();
backingIt.
set(
e);
nextSet(
idx,
lastReturned);
endChange();
}
@
Override
public void
add(E
e) {
beginChange();
int
idx =
nextIndex();
backingIt.
add(
e);
nextAdd(
idx,
idx + 1);
endChange();
}
};
}
@
Override
public
Iterator<E>
iterator() {
return
listIterator();
}
@
Override
public E
get(int
index) {
try {
return
backingList.
listIterator(
index).
next();
} catch (
NoSuchElementException exc) {
throw new
IndexOutOfBoundsException("Index: "+
index);
}
}
@
Override
public boolean
addAll(int
index,
Collection<? extends E>
c) {
try {
beginChange();
boolean
modified = false;
ListIterator<E>
e1 =
listIterator(
index);
Iterator<? extends E>
e2 =
c.
iterator();
while (
e2.
hasNext()) {
e1.
add(
e2.
next());
modified = true;
}
endChange();
return
modified;
} catch (
NoSuchElementException exc) {
throw new
IndexOutOfBoundsException("Index: "+
index);
}
}
@
Override
public int
size() {
return
backingList.
size();
}
@
Override
protected void
doAdd(int
index, E
element) {
try {
backingList.
listIterator(
index).
add(
element);
} catch (
NoSuchElementException exc) {
throw new
IndexOutOfBoundsException("Index: "+
index);
}
}
@
Override
protected E
doSet(int
index, E
element) {
try {
ListIterator<E>
e =
backingList.
listIterator(
index);
E
oldVal =
e.
next();
e.
set(
element);
return
oldVal;
} catch (
NoSuchElementException exc) {
throw new
IndexOutOfBoundsException("Index: "+
index);
}
}
@
Override
protected E
doRemove(int
index) {
try {
ListIterator<E>
e =
backingList.
listIterator(
index);
E
outCast =
e.
next();
e.
remove();
return
outCast;
} catch (
NoSuchElementException exc) {
throw new
IndexOutOfBoundsException("Index: "+
index);
}
}
@
Override
@
SuppressWarnings("unchecked")
public void
sort() {
if (
backingList.
isEmpty()) {
return;
}
int[]
perm =
getSortHelper().
sort((
List<? extends
Comparable>)
backingList);
fireChange(new
NonIterableChange.
SimplePermutationChange<E>(0,
size(),
perm, this));
}
@
Override
public void
sort(
Comparator<? super E>
comparator) {
if (
backingList.
isEmpty()) {
return;
}
int[]
perm =
getSortHelper().
sort(
backingList,
comparator);
fireChange(new
NonIterableChange.
SimplePermutationChange<E>(0,
size(),
perm, this));
}
private
SortHelper getSortHelper() {
if (
helper == null) {
helper = new
SortHelper();
}
return
helper;
}
}