mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 10:41:26 +00:00
Removed unused classes
This commit is contained in:
@@ -1,65 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.stage.Window;
|
||||
|
||||
/**
|
||||
* @deprecated use https://github.com/TomasMikula/EasyBind#conditional-collection-membership
|
||||
*/
|
||||
@Deprecated
|
||||
public class ActiveWindowStyleSupport implements ChangeListener<Boolean> {
|
||||
|
||||
public static final String ACTIVE_WINDOW_STYLE_CLASS = "active-window";
|
||||
public static final String INACTIVE_WINDOW_STYLE_CLASS = "inactive-window";
|
||||
|
||||
private final Window window;
|
||||
|
||||
private ActiveWindowStyleSupport(Window window) {
|
||||
this.window = window;
|
||||
this.addActiveWindowClassIfFocused(window.isFocused());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and registers a listener on the given window, that will add the class {@value #ACTIVE_WINDOW_STYLE_CLASS} to the scenes root element, if the window is active. Otherwise
|
||||
* {@value #INACTIVE_WINDOW_STYLE_CLASS} will be added. Allows CSS rules to be defined depending on the window's focus.<br/>
|
||||
* <br/>
|
||||
* Example:<br/>
|
||||
* <code>
|
||||
* .root.inactive-window .button {-fx-background-color: grey;}<br/>
|
||||
* .root.active-window .button {-fx-background-color: blue;}
|
||||
* </code>
|
||||
*
|
||||
* @param window The window to observe
|
||||
* @return The observer
|
||||
*/
|
||||
public static ChangeListener<Boolean> startObservingFocus(final Window window) {
|
||||
final ChangeListener<Boolean> observer = new ActiveWindowStyleSupport(window);
|
||||
window.focusedProperty().addListener(observer);
|
||||
return observer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
|
||||
this.addActiveWindowClassIfFocused(newValue);
|
||||
}
|
||||
|
||||
private void addActiveWindowClassIfFocused(Boolean focused) {
|
||||
if (Boolean.TRUE.equals(focused)) {
|
||||
window.getScene().getRoot().getStyleClass().add(ACTIVE_WINDOW_STYLE_CLASS);
|
||||
window.getScene().getRoot().getStyleClass().remove(INACTIVE_WINDOW_STYLE_CLASS);
|
||||
} else {
|
||||
window.getScene().getRoot().getStyleClass().remove(ACTIVE_WINDOW_STYLE_CLASS);
|
||||
window.getScene().getRoot().getStyleClass().add(INACTIVE_WINDOW_STYLE_CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* https://github.com/totalvoidness/FXThreads
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.ObservableSet;
|
||||
|
||||
/**
|
||||
* Use this utility class to spawn background tasks and wait for them to finish. <br/>
|
||||
* <br/>
|
||||
* <strong>Example use (ignoring exceptions):</strong>
|
||||
*
|
||||
* <pre>
|
||||
* // get some string from a remote server:
|
||||
* Future<String> futureBookName = runOnBackgroundThread(restResource::getBookName);
|
||||
*
|
||||
* // when done, update text label:
|
||||
* runOnMainThreadWhenFinished(futureBookName, (bookName) -> {
|
||||
* myLabel.setText(bookName);
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* <strong>Example use (exception-aware):</strong>
|
||||
*
|
||||
* <pre>
|
||||
* // get some string from a remote server:
|
||||
* Future<String> futureBookName = runOnBackgroundThread(restResource::getBookName);
|
||||
*
|
||||
* // when done, update text label:
|
||||
* runOnMainThreadWhenFinished(futureBookName, (bookName) -> {
|
||||
* myLabel.setText(bookName);
|
||||
* } , (exception) -> {
|
||||
* myLabel.setText("An exception occured: " + exception.getMessage());
|
||||
* });
|
||||
* </pre>
|
||||
*/
|
||||
public final class FXThreads {
|
||||
|
||||
private static final Consumer<Exception> DUMMY_EXCEPTION_CALLBACK = (e) -> {
|
||||
// ignore.
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits for the given task to complete and notifies the given successCallback. If an exception occurs, the callback will never be called. If you are interested in the exception, use
|
||||
* {@link #runOnMainThreadWhenFinished(ExecutorService, Future, CallbackWhenTaskFinished, CallbackWhenTaskFailed)} instead.
|
||||
*
|
||||
* <pre>
|
||||
* // example:
|
||||
*
|
||||
* runOnMainThreadWhenFinished(futureBookName, (bookName) -> {
|
||||
* myLabel.setText(bookName);
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param executor The service to execute the background task on
|
||||
* @param task The task to wait for.
|
||||
* @param successCallback The action to perform, when the task finished.
|
||||
*/
|
||||
public static <T> void runOnMainThreadWhenFinished(ExecutorService executor, Future<T> task, Consumer<T> successCallback) {
|
||||
runOnMainThreadWhenFinished(executor, task, successCallback, DUMMY_EXCEPTION_CALLBACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the given task to complete and notifies the given successCallback. If an exception occurs, the callback will never be called. If you are interested in the exception, use
|
||||
* {@link #runOnMainThreadWhenFinished(ExecutorService, Future, CallbackWhenTaskFinished, CallbackWhenTaskFailed)} instead.
|
||||
*
|
||||
* <pre>
|
||||
* // example:
|
||||
*
|
||||
* runOnMainThreadWhenFinished(futureBookNamePossiblyFailing, (bookName) -> {
|
||||
* myLabel.setText(bookName);
|
||||
* } , (exception) -> {
|
||||
* myLabel.setText("An exception occured: " + exception.getMessage());
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param executor The service to execute the background task on
|
||||
* @param task The task to wait for.
|
||||
* @param successCallback The action to perform, when the task finished.
|
||||
* @param exceptionCallback
|
||||
*/
|
||||
public static <T> void runOnMainThreadWhenFinished(ExecutorService executor, Future<T> task, Consumer<T> successCallback, Consumer<Exception> exceptionCallback) {
|
||||
Objects.requireNonNull(task, "task must not be null.");
|
||||
Objects.requireNonNull(successCallback, "successCallback must not be null.");
|
||||
Objects.requireNonNull(exceptionCallback, "exceptionCallback must not be null.");
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
final T result = task.get();
|
||||
Platform.runLater(() -> {
|
||||
successCallback.accept(result);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> {
|
||||
exceptionCallback.accept(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <E> ObservableSet<E> observableSetOnMainThread(ObservableSet<E> set) {
|
||||
return new ObservableSetOnMainThread<E>(set);
|
||||
}
|
||||
|
||||
public static <E> ObservableList<E> observableListOnMainThread(ObservableList<E> list) {
|
||||
return new ObservableListOnMainThread<E>(list);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 cryptomator.org
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Tillmann Gaida - initial implementation
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* Manages and broadcasts events to a set of listeners. The types of the
|
||||
* listener and event are entirely unbound. Instead, a method must be supplied
|
||||
* to broadcast an event to a single listener.
|
||||
*
|
||||
* @author Tillmann Gaida
|
||||
*
|
||||
* @param <LISTENER>
|
||||
* The type of listener.
|
||||
* @param <EVENT>
|
||||
* The type of event.
|
||||
*/
|
||||
public class ListenerRegistry<LISTENER, EVENT> {
|
||||
final BiConsumer<LISTENER, EVENT> listenerCaller;
|
||||
|
||||
/**
|
||||
* Constructs a new registry.
|
||||
*
|
||||
* @param listenerCaller
|
||||
* The method which broadcasts an event to a single listener.
|
||||
*/
|
||||
public ListenerRegistry(BiConsumer<LISTENER, EVENT> listenerCaller) {
|
||||
super();
|
||||
this.listenerCaller = listenerCaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* The handle of a registered listener.
|
||||
*/
|
||||
public interface ListenerRegistration {
|
||||
void unregister();
|
||||
}
|
||||
|
||||
final AtomicLong serial = new AtomicLong();
|
||||
/*
|
||||
* Since this is a {@link ConcurrentSkipListMap}, we can at the same time
|
||||
* add to, remove from, and iterate over it. More importantly, a Listener
|
||||
* can remove itself while being called from the {@link #broadcast(Object)}
|
||||
* method.
|
||||
*/
|
||||
final Map<Long, LISTENER> listeners = new ConcurrentSkipListMap<>();
|
||||
|
||||
public ListenerRegistration registerListener(LISTENER listener) {
|
||||
final long s = serial.incrementAndGet();
|
||||
|
||||
listeners.put(s, listener);
|
||||
|
||||
return () -> {
|
||||
listeners.remove(s);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts the given event to all registered listeners. If a listener
|
||||
* causes an unchecked exception, that exception is thrown immediately
|
||||
* without calling the other listeners.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void broadcast(EVENT event) {
|
||||
for (LISTENER listener : listeners.values()) {
|
||||
listenerCaller.accept(listener, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
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) {
|
||||
final Collection<InvalidationListener> listeners = ImmutableList.copyOf(invalidationListeners);
|
||||
Platform.runLater(() -> {
|
||||
for (InvalidationListener listener : listeners) {
|
||||
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);
|
||||
final Collection<ListChangeListener<? super E>> listeners = ImmutableList.copyOf(listChangeListeners);
|
||||
Platform.runLater(() -> {
|
||||
for (ListChangeListener<? super E> listener : listeners) {
|
||||
listener.onChanged(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ListChangeListener<? super E> listener) {
|
||||
listChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(ListChangeListener<? super E> listener) {
|
||||
listChangeListeners.remove(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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.collections.ObservableSet;
|
||||
import javafx.collections.SetChangeListener;
|
||||
import javafx.collections.SetChangeListener.Change;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
class ObservableSetOnMainThread<E> implements ObservableSet<E> {
|
||||
|
||||
private final ObservableSet<E> set;
|
||||
private final Collection<InvalidationListener> invalidationListeners;
|
||||
private final Collection<SetChangeListener<? super E>> setChangeListeners;
|
||||
|
||||
public ObservableSetOnMainThread(ObservableSet<E> set) {
|
||||
this.set = set;
|
||||
this.invalidationListeners = new HashSet<>();
|
||||
this.setChangeListeners = new HashSet<>();
|
||||
this.set.addListener(this::invalidated);
|
||||
this.set.addListener(this::onChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return set.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return set.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return set.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return set.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return set.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return set.toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
return set.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return set.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
return set.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
return set.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
return set.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
return set.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
set.clear();
|
||||
}
|
||||
|
||||
private void invalidated(Observable observable) {
|
||||
final Collection<InvalidationListener> listeners = ImmutableList.copyOf(invalidationListeners);
|
||||
Platform.runLater(() -> {
|
||||
for (InvalidationListener listener : listeners) {
|
||||
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 SetChange(this, change.getElementAdded(), change.getElementRemoved());
|
||||
final Collection<SetChangeListener<? super E>> listeners = ImmutableList.copyOf(setChangeListeners);
|
||||
Platform.runLater(() -> {
|
||||
for (SetChangeListener<? super E> listener : listeners) {
|
||||
listener.onChanged(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(SetChangeListener<? super E> listener) {
|
||||
setChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(SetChangeListener<? super E> listener) {
|
||||
setChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
private class SetChange extends SetChangeListener.Change<E> {
|
||||
|
||||
private final E added;
|
||||
private final E removed;
|
||||
|
||||
public SetChange(ObservableSet<E> set, E added, E removed) {
|
||||
super(set);
|
||||
this.added = added;
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasAdded() {
|
||||
return added != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasRemoved() {
|
||||
return removed != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getElementAdded() {
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getElementRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 cryptomator.org
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Tillmann Gaida - initial implementation
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
/**
|
||||
* A task which is supposed to be repeated until it succeeds.
|
||||
*
|
||||
* @author Tillmann Gaida
|
||||
*
|
||||
* @param <E>
|
||||
* The type of checked exception that this task may throw.
|
||||
*/
|
||||
public interface TimeoutTask<E extends Exception> {
|
||||
/**
|
||||
* Attempts to execute the task.
|
||||
*
|
||||
* @param timeout
|
||||
* The time remaining to finish the task.
|
||||
* @return true if the task finished, false if it needs to be attempted
|
||||
* again.
|
||||
* @throws E
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
boolean attempt(long timeout) throws E, InterruptedException;
|
||||
|
||||
/**
|
||||
* Attempts a task until a timeout occurs. Checks for this timeout are based
|
||||
* on {@link System#currentTimeMillis()}, so they are very crude. The task
|
||||
* is guaranteed to be attempted once.
|
||||
*
|
||||
* @param task
|
||||
* the task to perform.
|
||||
* @param timeout
|
||||
* time in millis before this method stops attempting to finish
|
||||
* the task. greater than zero.
|
||||
* @param sleepTimes
|
||||
* time in millis to sleep between attempts. greater than zero.
|
||||
* @return true if the task was finished, false if the task never always
|
||||
* returned false or as soon as the task throws an
|
||||
* {@link InterruptedException}.
|
||||
* @throws E
|
||||
* From the task.
|
||||
*/
|
||||
public static <E extends Exception> boolean attempt(TimeoutTask<E> task, long timeout, long sleepTimes) throws E {
|
||||
if (timeout <= 0 || sleepTimes <= 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
long tryUntil = currentTime + timeout;
|
||||
|
||||
for (;; currentTime = System.currentTimeMillis()) {
|
||||
if (currentTime >= tryUntil) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (task.attempt(tryUntil - currentTime)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
currentTime = System.currentTimeMillis();
|
||||
|
||||
if (currentTime + sleepTimes < tryUntil) {
|
||||
Thread.sleep(sleepTimes);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 cryptomator.org
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Tillmann Gaida - initial implementation
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ListenerRegistryTest {
|
||||
/**
|
||||
* This test looks at how concurrent modifications affect the iterator of a
|
||||
* {@link ConcurrentSkipListMap}. It shows that concurrent modifications
|
||||
* work just fine, however the state of the iterator including the next
|
||||
* value are advanced during retrieval of a value, so it's not possible to
|
||||
* remove the next value.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testConcurrentSkipListMap() throws Exception {
|
||||
ConcurrentSkipListMap<Integer, Integer> map = new ConcurrentSkipListMap<>();
|
||||
|
||||
map.put(1, 1);
|
||||
map.put(2, 2);
|
||||
map.put(3, 3);
|
||||
map.put(4, 4);
|
||||
map.put(5, 5);
|
||||
|
||||
final Iterator<Integer> iterator = map.values().iterator();
|
||||
|
||||
assertTrue(iterator.hasNext());
|
||||
assertEquals((Integer) 1, iterator.next());
|
||||
map.remove(2);
|
||||
assertTrue(iterator.hasNext());
|
||||
// iterator returns 2 anyway.
|
||||
assertEquals((Integer) 2, iterator.next());
|
||||
assertTrue(iterator.hasNext());
|
||||
map.remove(4);
|
||||
assertEquals((Integer) 3, iterator.next());
|
||||
assertTrue(iterator.hasNext());
|
||||
// this time we removed 4 before retrieving 3, so it is skipped.
|
||||
assertEquals((Integer) 5, iterator.next());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user