Il n'y a pas longtemps, j'ai écrit un article tel que "JavaFX peut faire assez de liaison de données!" Impression de création d'une application chronomètre avec Java + JavaFX + MVVM Ce n'est pas sufisant! Pas assez! ** Plus précisément ** Je veux écrire en génériques! ** ** C'est une «propriété de chaîne», une «propriété booléenne», ** Vous ne pensiez pas que c'était un millimètre de merde lorsque vous l'avez implémentée ** et a été nommé pour demander aux développeurs Java (Sun ou Oracle) pendant une heure. Je regardais le cours dans lequel j'étais. "Alors faisons une propriété réactive après avoir pratiqué les génériques."
Pour le moment, j'ai décidé d'hériter de l'interface Propriété <T>
tout en ayant une instance de type Propriété <T>
à l'intérieur. L'entité doit être un SimpleObjectProperty <T>
qui hérite de la Property <T>
, peut-être.
sample1.java
public class ReactiveProperty<T> implements Property<T> {
private Property<T> value;
//constructeur
public ReactiveProperty(){
value = new SimpleObjectProperty<>();
}
public ReactiveProperty(T t){
value = new SimpleObjectProperty<>(t);
}
}
Puisque nous avons hérité de la propriété est une méthode d'argument, comme
public void setValue (Object value) {this.value.setValue ((T) value);} `. n'est-ce pas…….
Je vise une alternative, donc j'aimerais implémenter des méthodes majeures telles que «Select» et «Subscribe». Concernant la méthode de notification, comme l'instance interne a la méthode ʻaddListener`, j'ai décidé de l'ajouter ici. C'est incroyable que la fonction de notification fonctionne correctement avec juste cela.
Cependant, Java n'a pas le concept de "méthode d'extension", donc le résultat de "Select" devient soudainement "ReactiveProperty
sample2.java
public class ReactiveProperty<T> implements Property<T> {
//Créer ReactiveProperty à partir de 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;
}
//Créer une propriété réactive à partir de deux propriétés réactives
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;
}
//Créer une propriété réactive à partir de ◯◯ Propriété
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;
}
//Modifier la fonction de notification
public void subscribe(Consumer<T> cons){
this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
}
}
En implémentant comme ci-dessus, nous avons pu créer une propriété avec notification par génériques. Lorsque je l'ai apporté à un projet JavaFX et que je l'ai utilisé, il hérite de Property <T>
, donc il peut être correctement Data Binding avec la propriété du contrôle, donc cela semble être assez utile.
Veuillez noter qu'il s'agit d'un code merdique écrit par un débutant Java. Je suis désolé que le nom du package soit Pour ceux qui ont implémenté LINQ en Java. Est-il également nécessaire de changer le nom du modèle ...?
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;
//constructeur
public ReactiveProperty(){
value = new SimpleObjectProperty<>();
}
public ReactiveProperty(T t){
value = new SimpleObjectProperty<>(t);
}
//Parce qu'il hérite de l'interface 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();}
//Créer ReactiveProperty à partir de 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;
}
//Créer une propriété réactive à partir de deux propriétés réactives
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;
}
//Créer une propriété réactive à partir de ◯◯ Propriété
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;
}
//Modifier la fonction de notification
public void subscribe(Consumer<T> cons){
this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
}
}
Recommended Posts