Vor nicht allzu langer Zeit schrieb ich einen Artikel wie "JavaFX kann genug Datenbindung!" Eindruck der Erstellung einer Stoppuhr-App mit Java + JavaFX + MVVM ** Dies ist jedoch nicht genug! Nicht genug! ** Speziell ** Ich möchte in Generics schreiben! ** ** ** Es ist eine "String-Eigenschaft", eine "Boolesche Eigenschaft". ** Hast du nicht gedacht, dass es ein Millimeter Scheiße war, als du sie implementiert hast? ** und wurde benannt, um Java-Entwickler (Sun oder Oracle) eine Stunde lang zu fragen. Ich habe mir die Klasse angesehen, in der ich war. "Dann machen wir eine reaktive Eigenschaft, nachdem wir Generika geübt haben."
Vorerst habe ich beschlossen, die Schnittstelle "Property
sample1.java
public class ReactiveProperty<T> implements Property<T> {
private Property<T> value;
//Konstrukteur
public ReactiveProperty(){
value = new SimpleObjectProperty<>();
}
public ReactiveProperty(T t){
value = new SimpleObjectProperty<>(t);
}
}
Da wir "Property
Ich strebe eine Alternative an, daher möchte ich wichtige Methoden wie "Auswählen" und "Abonnieren" implementieren. In Bezug auf die Benachrichtigungsmethode habe ich beschlossen, diese dort hinzuzufügen, da die interne Instanz über eine Methode "addListener" verfügt. Es ist erstaunlich, dass die Benachrichtigungsfunktion genau damit richtig funktioniert.
Java hat jedoch nicht das Konzept der "Erweiterungsmethode", so dass das Ergebnis von "Select" plötzlich zu "ReactiveProperty
sample2.java
public class ReactiveProperty<T> implements Property<T> {
//Erstellen Sie ReactiveProperty aus 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;
}
//Erstellen Sie eine reaktive Eigenschaft aus zwei reaktiven Eigenschaften
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;
}
//Erstellen Sie eine reaktive Eigenschaft aus der Eigenschaft ◯◯
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;
}
//Benachrichtigungsfunktion ändern
public void subscribe(Consumer<T> cons){
this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
}
}
Durch die Implementierung wie oben konnten wir eine Eigenschaft mit Benachrichtigung durch Generika erstellen. Wenn ich es in ein JavaFX-Projekt gebracht und verwendet habe, erbt es "Property
Bitte beachten Sie, dass dies ein beschissener Code ist, der von einem Java-Anfänger geschrieben wurde. Es tut mir leid, dass der Paketname [Für diejenigen, die LINQ in Java implementiert haben] lautet (https://qiita.com/kasecato/items/ec7ab8b392fa8bb0a732#%E8%AA%B2%E9%A1%8C). Muss auch der Modellname geändert werden ...?
ReactiveProperty.java
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;
//Konstrukteur
public ReactiveProperty(){
value = new SimpleObjectProperty<>();
}
public ReactiveProperty(T t){
value = new SimpleObjectProperty<>(t);
}
//Weil es die Eigenschaftsschnittstelle erbt ...
@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();}
//Erstellen Sie ReactiveProperty aus 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;
}
//Erstellen Sie eine reaktive Eigenschaft aus zwei reaktiven Eigenschaften
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;
}
//Erstellen Sie eine reaktive Eigenschaft aus der Eigenschaft ◯◯
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;
}
//Benachrichtigungsfunktion ändern
public void subscribe(Consumer<T> cons){
this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
}
}
Recommended Posts