|
@@ -0,0 +1,272 @@
|
|
|
+package org.cryptomator.ui.util;
|
|
|
+
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.ListIterator;
|
|
|
+
|
|
|
+import javafx.application.Platform;
|
|
|
+import javafx.beans.InvalidationListener;
|
|
|
+import javafx.beans.Observable;
|
|
|
+import javafx.collections.ListChangeListener;
|
|
|
+import javafx.collections.ListChangeListener.Change;
|
|
|
+import javafx.collections.ObservableList;
|
|
|
+
|
|
|
+class ObservableListOnMainThread<E> implements ObservableList<E> {
|
|
|
+
|
|
|
+ private final ObservableList<E> list;
|
|
|
+ private final Collection<InvalidationListener> invalidationListeners;
|
|
|
+ private final Collection<ListChangeListener<? super E>> listChangeListeners;
|
|
|
+
|
|
|
+ public ObservableListOnMainThread(ObservableList<E> list) {
|
|
|
+ this.list = list;
|
|
|
+ this.invalidationListeners = new HashSet<>();
|
|
|
+ this.listChangeListeners = new HashSet<>();
|
|
|
+ this.list.addListener(this::invalidated);
|
|
|
+ this.list.addListener(this::onChanged);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int size() {
|
|
|
+ return list.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isEmpty() {
|
|
|
+ return list.isEmpty();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean contains(Object o) {
|
|
|
+ return list.contains(o);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Iterator<E> iterator() {
|
|
|
+ return list.iterator();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object[] toArray() {
|
|
|
+ return list.toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public <T> T[] toArray(T[] a) {
|
|
|
+ return list.toArray(a);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean add(E e) {
|
|
|
+ return list.add(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean remove(Object o) {
|
|
|
+ return list.remove(o);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean containsAll(Collection<?> c) {
|
|
|
+ return list.containsAll(c);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean addAll(Collection<? extends E> c) {
|
|
|
+ return list.addAll(c);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean addAll(int index, Collection<? extends E> c) {
|
|
|
+ return list.addAll(index, c);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean removeAll(Collection<?> c) {
|
|
|
+ return list.removeAll(c);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean retainAll(Collection<?> c) {
|
|
|
+ return list.retainAll(c);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void clear() {
|
|
|
+ list.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public E get(int index) {
|
|
|
+ return list.get(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public E set(int index, E element) {
|
|
|
+ return list.set(index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void add(int index, E element) {
|
|
|
+ list.add(index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public E remove(int index) {
|
|
|
+ return list.remove(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int indexOf(Object o) {
|
|
|
+ return list.indexOf(o);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int lastIndexOf(Object o) {
|
|
|
+ return list.lastIndexOf(o);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ListIterator<E> listIterator() {
|
|
|
+ return list.listIterator();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ListIterator<E> listIterator(int index) {
|
|
|
+ return list.listIterator(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<E> subList(int fromIndex, int toIndex) {
|
|
|
+ return list.subList(fromIndex, toIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean addAll(@SuppressWarnings("unchecked") E... elements) {
|
|
|
+ return list.addAll(elements);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean setAll(@SuppressWarnings("unchecked") E... elements) {
|
|
|
+ return list.addAll(elements);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean setAll(Collection<? extends E> col) {
|
|
|
+ return list.setAll(col);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean removeAll(@SuppressWarnings("unchecked") E... elements) {
|
|
|
+ return list.removeAll(elements);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean retainAll(@SuppressWarnings("unchecked") E... elements) {
|
|
|
+ return list.retainAll(elements);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void remove(int from, int to) {
|
|
|
+ list.remove(from, to);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void invalidated(Observable observable) {
|
|
|
+ Platform.runLater(() -> {
|
|
|
+ for (InvalidationListener listener : invalidationListeners) {
|
|
|
+ listener.invalidated(this);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addListener(InvalidationListener listener) {
|
|
|
+ invalidationListeners.add(listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void removeListener(InvalidationListener listener) {
|
|
|
+ invalidationListeners.remove(listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void onChanged(Change<? extends E> change) {
|
|
|
+ final Change<? extends E> c = new ListChange(change);
|
|
|
+ Platform.runLater(() -> {
|
|
|
+ for (ListChangeListener<? super E> listener : listChangeListeners) {
|
|
|
+ listener.onChanged(c);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addListener(ListChangeListener<? super E> listener) {
|
|
|
+ listChangeListeners.add(listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void removeListener(ListChangeListener<? super E> listener) {
|
|
|
+ listChangeListeners.add(listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ private class ListChange extends ListChangeListener.Change<E> {
|
|
|
+
|
|
|
+ private final Change<? extends E> originalChange;
|
|
|
+
|
|
|
+ public ListChange(Change<? extends E> change) {
|
|
|
+ super(ObservableListOnMainThread.this);
|
|
|
+ this.originalChange = change;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean wasAdded() {
|
|
|
+ return originalChange.wasAdded();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean wasRemoved() {
|
|
|
+ return originalChange.wasRemoved();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean next() {
|
|
|
+ return originalChange.next();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void reset() {
|
|
|
+ originalChange.reset();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getFrom() {
|
|
|
+ return originalChange.getFrom();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getTo() {
|
|
|
+ return originalChange.getTo();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public List<E> getRemoved() {
|
|
|
+ return (List<E>) originalChange.getRemoved();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected int[] getPermutation() {
|
|
|
+ if (originalChange.wasPermutated()) {
|
|
|
+ int[] permutations = new int[originalChange.getTo() - originalChange.getFrom()];
|
|
|
+ for (int i = 0; i < permutations.length; i++) {
|
|
|
+ permutations[i] = originalChange.getPermutation(i);
|
|
|
+ }
|
|
|
+ return permutations;
|
|
|
+ } else {
|
|
|
+ return new int[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|