-
-
Save mstr2/1efc9e866f81622253711a963bd272fc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sun.javafx.binding; | |
import javafx.beans.InvalidationListener; | |
import javafx.beans.value.ChangeListener; | |
import javafx.beans.value.ObservableValue; | |
import java.util.Objects; | |
import java.util.Queue; | |
import java.util.concurrent.ConcurrentLinkedQueue; | |
public abstract class ConcurrentExpressionHelper<T> extends ExpressionHelperBase { | |
public static <T> ConcurrentExpressionHelper<T> addListener( | |
ConcurrentExpressionHelper<T> helper, ObservableValue<T> observable, InvalidationListener listener) { | |
if ((observable == null) || (listener == null)) { | |
throw new NullPointerException(); | |
} | |
observable.getValue(); // validate observable | |
return helper == null ? new Invalidation1<>(observable, listener) : helper.addListener(listener); | |
} | |
public static <T> ConcurrentExpressionHelper<T> removeListener( | |
ConcurrentExpressionHelper<T> helper, InvalidationListener listener) { | |
if (listener == null) { | |
throw new NullPointerException(); | |
} | |
return helper == null ? null : helper.removeListener(listener); | |
} | |
public static <T> ConcurrentExpressionHelper<T> addListener( | |
ConcurrentExpressionHelper<T> helper, ObservableValue<T> observable, ChangeListener<? super T> listener) { | |
if ((observable == null) || (listener == null)) { | |
throw new NullPointerException(); | |
} | |
return helper == null ? new Change1<>(observable, listener) : helper.addListener(listener); | |
} | |
public static <T> ConcurrentExpressionHelper<T> removeListener( | |
ConcurrentExpressionHelper<T> helper, ChangeListener<? super T> listener) { | |
if (listener == null) { | |
throw new NullPointerException(); | |
} | |
return helper == null ? null : helper.removeListener(listener); | |
} | |
public static <T> void fireValueChangedEvent(ConcurrentExpressionHelper<T> helper) { | |
if (helper != null) { | |
helper.fireValueChangedEvent(); | |
} | |
} | |
final ObservableValue<T> observable; | |
private ConcurrentExpressionHelper(ObservableValue<T> observable) { | |
this.observable = observable; | |
} | |
abstract ConcurrentExpressionHelper<T> addListener(InvalidationListener listener); | |
abstract ConcurrentExpressionHelper<T> removeListener(InvalidationListener listener); | |
abstract ConcurrentExpressionHelper<T> addListener(ChangeListener<? super T> listener); | |
abstract ConcurrentExpressionHelper<T> removeListener(ChangeListener<? super T> listener); | |
abstract void fireValueChangedEvent(); | |
static class Invalidation1<T> extends ConcurrentExpressionHelper<T> { | |
final InvalidationListener listener1; | |
Invalidation1(ObservableValue<T> observable, InvalidationListener listener) { | |
super(observable); | |
this.listener1 = Objects.requireNonNull(listener); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(InvalidationListener listener) { | |
return new Invalidation3<>(observable, listener1, listener, null); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(InvalidationListener listener) { | |
return listener.equals(listener1) ? null : this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(ChangeListener<? super T> listener) { | |
return new Invalidation3Change3<>(observable, listener1, null, null, listener, null, null); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(ChangeListener<? super T> listener) { | |
return this; | |
} | |
@Override | |
void fireValueChangedEvent() { | |
try { | |
listener1.invalidated(observable); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
} | |
static class Invalidation3<T> extends ConcurrentExpressionHelper<T> { | |
final InvalidationListener listener1; | |
final InvalidationListener listener2; | |
final InvalidationListener listener3; | |
Invalidation3(ObservableValue<T> observable, | |
InvalidationListener listener1, | |
InvalidationListener listener2, | |
InvalidationListener listener3) { | |
super(observable); | |
this.listener1 = Objects.requireNonNull(listener1); | |
this.listener2 = Objects.requireNonNull(listener2); | |
this.listener3 = listener3; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(InvalidationListener listener) { | |
if (listener3 == null) { | |
return new Invalidation3<>(observable, listener1, listener2, listener); | |
} | |
var helper = new Generic<>(observable, listener1, listener2, listener3, null, null, null); | |
helper.invalidationListeners.add(listener); | |
return helper; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(InvalidationListener listener) { | |
if (listener.equals(listener3)) { | |
return new Invalidation3<>(observable, listener1, listener2, null); | |
} | |
if (listener.equals(listener2)) { | |
return listener3 != null ? | |
new Invalidation3<>(observable, listener1, listener3, null) : | |
new Invalidation1<>(observable, listener1); | |
} | |
if (listener.equals(listener1)) { | |
return listener3 != null ? | |
new Invalidation3<>(observable, listener2, listener3, null) : | |
new Invalidation1<>(observable, listener2); | |
} | |
return this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(ChangeListener<? super T> listener) { | |
return new Invalidation3Change3<>(observable, listener1, listener2, listener3, listener, null, null); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(ChangeListener<? super T> listener) { | |
return this; | |
} | |
@Override | |
void fireValueChangedEvent() { | |
fireValueChangedEvent(listener1); | |
fireValueChangedEvent(listener2); | |
fireValueChangedEvent(listener3); | |
} | |
private void fireValueChangedEvent(InvalidationListener listener) { | |
if (listener != null) { | |
try { | |
listener.invalidated(observable); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
} | |
} | |
static class Change1<T> extends ConcurrentExpressionHelper<T> { | |
final ChangeListener<? super T> listener; | |
T currentValue; | |
Change1(ObservableValue<T> observable, ChangeListener<? super T> listener) { | |
super(observable); | |
this.listener = listener; | |
this.currentValue = observable.getValue(); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(InvalidationListener listener) { | |
return new Invalidation3Change3<>( | |
observable, listener, null, null, this.listener, null, null); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(InvalidationListener listener) { | |
return this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(ChangeListener<? super T> listener) { | |
return new Change3<>(observable, this.listener, listener, null); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(ChangeListener<? super T> listener) { | |
return listener.equals(this.listener) ? null : this; | |
} | |
@Override | |
void fireValueChangedEvent() { | |
T oldValue = currentValue; | |
currentValue = observable.getValue(); | |
if (!Objects.equals(currentValue, oldValue)) { | |
try { | |
listener.changed(observable, oldValue, currentValue); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
} | |
} | |
static class Change3<T> extends ConcurrentExpressionHelper<T> { | |
final ChangeListener<? super T> listener1; | |
final ChangeListener<? super T> listener2; | |
final ChangeListener<? super T> listener3; | |
T currentValue; | |
Change3(ObservableValue<T> observable, | |
ChangeListener<? super T> listener1, | |
ChangeListener<? super T> listener2, | |
ChangeListener<? super T> listener3) { | |
super(observable); | |
this.listener1 = Objects.requireNonNull(listener1); | |
this.listener2 = Objects.requireNonNull(listener2); | |
this.listener3 = listener3; | |
this.currentValue = observable.getValue(); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(InvalidationListener listener) { | |
return new Invalidation3Change3<>( | |
observable, listener, null, null, listener1, listener2, listener3); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(InvalidationListener listener) { | |
return this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(ChangeListener<? super T> listener) { | |
if (listener3 == null) { | |
return new Change3<>(observable, listener1, listener2, listener); | |
} | |
var helper = new Generic<>(observable, null, null, null, listener1, listener2, listener3); | |
helper.changeListeners.add(listener); | |
return helper; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(ChangeListener<? super T> listener) { | |
if (listener.equals(listener3)) { | |
return new Change3<>(observable, listener1, listener2, null); | |
} | |
if (listener.equals(listener2)) { | |
return listener3 != null ? | |
new Change3<>(observable, listener1, listener3, null) : | |
new Change1<>(observable, listener1); | |
} | |
if (listener.equals(listener1)) { | |
return listener3 != null ? | |
new Change3<>(observable, listener2, listener3, null) : | |
new Change1<>(observable, listener2); | |
} | |
return this; | |
} | |
@Override | |
void fireValueChangedEvent() { | |
T oldValue = currentValue; | |
currentValue = observable.getValue(); | |
if (!Objects.equals(currentValue, oldValue)) { | |
fireValueChangedEvent(listener1, oldValue); | |
fireValueChangedEvent(listener2, oldValue); | |
fireValueChangedEvent(listener3, oldValue); | |
} | |
} | |
private void fireValueChangedEvent(ChangeListener<? super T> listener, T oldValue) { | |
if (listener != null) { | |
try { | |
listener.changed(observable, oldValue, currentValue); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
} | |
} | |
static class Invalidation3Change3<T> extends ConcurrentExpressionHelper<T> { | |
final InvalidationListener invalidate1; | |
final InvalidationListener invalidate2; | |
final InvalidationListener invalidate3; | |
final ChangeListener<? super T> change1; | |
final ChangeListener<? super T> change2; | |
final ChangeListener<? super T> change3; | |
T currentValue; | |
Invalidation3Change3(ObservableValue<T> observable, | |
InvalidationListener invalidate1, | |
InvalidationListener invalidate2, | |
InvalidationListener invalidate3, | |
ChangeListener<? super T> change1, | |
ChangeListener<? super T> change2, | |
ChangeListener<? super T> change3) { | |
super(observable); | |
this.invalidate1 = Objects.requireNonNull(invalidate1); | |
this.invalidate2 = invalidate2; | |
this.invalidate3 = invalidate3; | |
this.change1 = Objects.requireNonNull(change1); | |
this.change2 = change2; | |
this.change3 = change3; | |
this.currentValue = observable.getValue(); | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(InvalidationListener listener) { | |
if (invalidate2 == null) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, listener, null, change1, change2, change3); | |
} | |
if (invalidate3 == null) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate2, listener, change1, change2, change3); | |
} | |
var helper = new Generic<>(observable, invalidate1, invalidate2, invalidate3, change1, change2, change3); | |
helper.invalidationListeners.add(listener); | |
return helper; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(InvalidationListener listener) { | |
if (listener.equals(invalidate1)) { | |
if (invalidate2 == null) { | |
return change2 != null ? | |
new Change3<>(observable, change1, change2, change3) : | |
new Change1<>(observable, change1); | |
} | |
return new Invalidation3Change3<>( | |
observable, invalidate2, invalidate3, null, change1, change2, change3); | |
} | |
if (listener.equals(invalidate2)) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate3, null, change1, change2, change3); | |
} | |
if (listener.equals(invalidate3)) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate2, null, change1, change2, change3); | |
} | |
return this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(ChangeListener<? super T> listener) { | |
if (change2 == null) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate2, invalidate3, change1, listener, null); | |
} | |
if (change3 == null) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate2, invalidate3, change1, change2, listener); | |
} | |
var helper = new Generic<>(observable, invalidate1, invalidate2, invalidate3, change1, change2, change3); | |
helper.changeListeners.add(listener); | |
return helper; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(ChangeListener<? super T> listener) { | |
if (listener.equals(change1)) { | |
if (change2 == null) { | |
return invalidate2 != null ? | |
new Invalidation3<>(observable, invalidate1, invalidate2, invalidate3) : | |
new Invalidation1<>(observable, invalidate1); | |
} | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate3, invalidate3, change2, change3, null); | |
} | |
if (listener.equals(change2)) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate2, invalidate3, change1, change3, null); | |
} | |
if (listener.equals(change3)) { | |
return new Invalidation3Change3<>( | |
observable, invalidate1, invalidate2, invalidate3, change1, change2, null); | |
} | |
return this; | |
} | |
@Override | |
void fireValueChangedEvent() { | |
fireValueChangedEvent(invalidate1); | |
fireValueChangedEvent(invalidate2); | |
fireValueChangedEvent(invalidate3); | |
T oldValue = currentValue; | |
currentValue = observable.getValue(); | |
if (!Objects.equals(currentValue, oldValue)) { | |
fireValueChangedEvent(change1, oldValue); | |
fireValueChangedEvent(change2, oldValue); | |
fireValueChangedEvent(change3, oldValue); | |
} | |
} | |
private void fireValueChangedEvent(InvalidationListener listener) { | |
if (listener != null) { | |
try { | |
listener.invalidated(observable); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
} | |
private void fireValueChangedEvent(ChangeListener<? super T> listener, T oldValue) { | |
if (listener != null) { | |
try { | |
listener.changed(observable, oldValue, currentValue); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
} | |
} | |
static class Generic<T> extends ConcurrentExpressionHelper<T> { | |
final Queue<InvalidationListener> invalidationListeners = new ConcurrentLinkedQueue<>(); | |
final Queue<ChangeListener<? super T>> changeListeners = new ConcurrentLinkedQueue<>(); | |
T currentValue; | |
Generic(ObservableValue<T> observable, | |
InvalidationListener invalidate0, | |
InvalidationListener invalidate1, | |
InvalidationListener invalidate2, | |
ChangeListener<? super T> change0, | |
ChangeListener<? super T> change1, | |
ChangeListener<? super T> change2) { | |
super(observable); | |
if (invalidate0 != null) { | |
invalidationListeners.add(invalidate0); | |
if (invalidate1 != null) invalidationListeners.add(invalidate1); | |
if (invalidate2 != null) invalidationListeners.add(invalidate2); | |
} | |
if (change0 != null) { | |
currentValue = observable.getValue(); | |
changeListeners.add(change0); | |
if (change1 != null) changeListeners.add(change1); | |
if (change2 != null) changeListeners.add(change2); | |
} | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(InvalidationListener listener) { | |
invalidationListeners.add(listener); | |
return this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(InvalidationListener listener) { | |
invalidationListeners.remove(listener); | |
return this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> addListener(ChangeListener<? super T> listener) { | |
currentValue = observable.getValue(); | |
changeListeners.add(listener); | |
return this; | |
} | |
@Override | |
ConcurrentExpressionHelper<T> removeListener(ChangeListener<? super T> listener) { | |
changeListeners.remove(listener); | |
return this; | |
} | |
@Override | |
void fireValueChangedEvent() { | |
for (InvalidationListener listener : invalidationListeners) { | |
try { | |
listener.invalidated(observable); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
T oldValue = currentValue; | |
currentValue = observable.getValue(); | |
if (!Objects.equals(currentValue, oldValue)) { | |
for (ChangeListener<? super T> listener : changeListeners) { | |
try { | |
listener.changed(observable, oldValue, currentValue); | |
} catch (Exception e) { | |
Thread currentThread = Thread.currentThread(); | |
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment