Skip to content

Instantly share code, notes, and snippets.

@YSRKEN
Created April 12, 2018 03:13
Show Gist options
  • Save YSRKEN/4913746ef2ec185873c1608f318a6e53 to your computer and use it in GitHub Desktop.
Save YSRKEN/4913746ef2ec185873c1608f318a6e53 to your computer and use it in GitHub Desktop.
JavaでもReactivePropertyしたいだけの人生だった ref: https://qiita.com/YSRKEN/items/723ebdc067dd8dd3ab42
package com.github.jrper;
import javafx.beans.InvalidationListener;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
public class ReactiveProperty<T> implements Property<T> {
private Property<T> value;
// コンストラクタ
public ReactiveProperty(){
value = new SimpleObjectProperty<>();
}
public ReactiveProperty(T t){
value = new SimpleObjectProperty<>(t);
}
// Propertyインターフェースを継承するので……
@Override
public void addListener(ChangeListener listener) {value.addListener(listener);}
@Override
public void removeListener(ChangeListener listener) {value.removeListener(listener);}
@Override
public void setValue(Object value){this.value.setValue((T)value);}
@Override
public void bind(ObservableValue observable) {value.bind(observable);}
@Override
public void unbind() {value.unbind();}
@Override
public boolean isBound() {return value.isBound();}
@Override
public void bindBidirectional(Property other) {value.bindBidirectional(other);}
@Override
public void unbindBidirectional(Property other) {value.unbindBidirectional(other);}
@Override
public Object getBean() {return value.getBean();}
@Override
public String getName() {return value.getName();}
@Override
public void addListener(InvalidationListener listener) {value.addListener(listener);}
@Override
public void removeListener(InvalidationListener listener) {value.removeListener(listener);}
// getter
public T getValue(){return value.getValue();}
// ReactivePropertyからReactivePropertyを作成
public <R> ReactiveProperty<R> select(Function<T, R> func){
ReactiveProperty<R> retVal = new ReactiveProperty<>(func.apply(this.getValue()));
this.addListener((sb, oldValue, newValue)->{retVal.setValue(func.apply((T)newValue));});
return retVal;
}
// 2つのReactivePropertyからReactivePropertyを作成
public <U, R> ReactiveProperty<R> combineLatest(ReactiveProperty<U> u, BiFunction<T, U, R> func){
ReactiveProperty<R> retVal = new ReactiveProperty<>(func.apply(this.getValue(), u.getValue()));
this.addListener((sb, oldValue, newValue)->{retVal.setValue(func.apply((T)newValue, u.getValue()));});
u.addListener((sb, oldValue, newValue)->{retVal.setValue(func.apply(this.getValue(), (U)newValue));});
return retVal;
}
// ◯◯PropertyからReactivePropertyを作成
public static <R> ReactiveProperty<R> ToReactiveProperty(Property<R> r){
ReactiveProperty<R> retVal = new ReactiveProperty<>(r.getValue());
r.addListener((sb, oldValue, newValue)->{retVal.setValue(r.getValue());});
return retVal;
}
// 変更通知機能
public void subscribe(Consumer<T> cons){
this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
}
}
public class ReactiveProperty<T> implements Property<T> {
private Property<T> value;
// コンストラクタ
public ReactiveProperty(){
value = new SimpleObjectProperty<>();
}
public ReactiveProperty(T t){
value = new SimpleObjectProperty<>(t);
}
}
public class ReactiveProperty<T> implements Property<T> {
// ReactivePropertyからReactivePropertyを作成
public <R> ReactiveProperty<R> select(Function<T, R> func){
ReactiveProperty<R> retVal = new ReactiveProperty<>(func.apply(this.getValue()));
this.addListener((sb, oldValue, newValue)->{retVal.setValue(func.apply((T)newValue));});
return retVal;
}
// 2つのReactivePropertyからReactivePropertyを作成
public <U, R> ReactiveProperty<R> combineLatest(ReactiveProperty<U> u, BiFunction<T, U, R> func){
ReactiveProperty<R> retVal = new ReactiveProperty<>(func.apply(this.getValue(), u.getValue()));
this.addListener((sb, oldValue, newValue)->{retVal.setValue(func.apply((T)newValue, u.getValue()));});
u.addListener((sb, oldValue, newValue)->{retVal.setValue(func.apply(this.getValue(), (U)newValue));});
return retVal;
}
// ◯◯PropertyからReactivePropertyを作成
public static <R> ReactiveProperty<R> ToReactiveProperty(Property<R> r){
ReactiveProperty<R> retVal = new ReactiveProperty<>(r.getValue());
r.addListener((sb, oldValue, newValue)->{retVal.setValue(r.getValue());});
return retVal;
}
// 変更通知機能
public void subscribe(Consumer<T> cons){
this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment