I just wanted to make a Reactive Property in Java

Overview

Not long ago, I wrote an article such as "JavaFX can do enough Data Binding!" Impression of creating a stopwatch app with Java + JavaFX + MVVM However, ** this is not enough! Not enough! ** Specifically ** I want to write in Generics! ** ** It's a String Property, a Boolean Property, ** You didn't think it was a millimeter of shit when you implemented it **, and it was named to ask Java developers (Sun or Oracle) for an hour. I was looking at the class I was in. "Then let's make a Reactive Property after practicing generics."

What to base

For the time being, I decided to inherit the interface Property <T> while having an instance of type Property <T> inside. The entity should be a SimpleObjectProperty <T> that inherits from the Property <T>, maybe.

sample1.java


public class ReactiveProperty<T> implements Property<T> {
    private Property<T> value;
    //constructor
    public ReactiveProperty(){
        value = new SimpleObjectProperty<>();
    }
    public ReactiveProperty(T t){
        value = new SimpleObjectProperty<>(t);
    }
}

Since we inherited Property <T>, we naturally need to implement various methods, but we threw them all into the internal instance (the code is omitted because it is redundant). However, it is unpleasant to have to write a cast when the ʻObject type is an argument method, such as public void setValue (Object value) {this.value.setValue ((T) value);} `. is not it…….

Let's implement a method like ReactiveProperty

I'm aiming for an alternative, so I'd like to implement major methods such as Select and Subscribe. Regarding the notification method, since the internal instance has a ʻaddListenermethod, I decided to add it there. It's amazing that the notification function works properly with just this. However, Java does not have the concept of "extension method", so the result ofSelect suddenly becomes ReactiveProperty , and ToReactivePropertyreplacesStringProperty etc. with ReactiveProperty `. It's just a method for you.

sample2.java


public class ReactiveProperty<T> implements Property<T> {
    //Create ReactiveProperty from 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;
    }
    //Create a Reactive Property from two Reactive Properties
    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;
    }
    //Create Reactive Property from ◯◯ Property
    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;
    }
    //Change notification function
    public void subscribe(Consumer<T> cons){
        this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
    }
}

Summary

By implementing as above, I was able to create a property with notification by generics. When I brought it to a JavaFX project and used it, it inherits Property <T>, so it can be Data-bound properly with the property of the control, so it seems to be useful enough.

Whole source code

This is a crappy code written by a Java beginner, but please understand. I'm sorry that the package name is For those who implemented LINQ in Java. Is it necessary to change the model name as well ...?

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;
    //constructor
    public ReactiveProperty(){
        value = new SimpleObjectProperty<>();
    }
    public ReactiveProperty(T t){
        value = new SimpleObjectProperty<>(t);
    }

    //Because it inherits the Property interface ...
    @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();}

    //Create ReactiveProperty from 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;
    }
    //Create a Reactive Property from two Reactive Properties
    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;
    }
    //Create Reactive Property from ◯◯ Property
    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;
    }
    //Change notification function
    public void subscribe(Consumer<T> cons){
        this.addListener((sb, oldValue, newValue) -> {cons.accept(this.getValue());});
    }
}

Recommended Posts

I just wanted to make a Reactive Property in Java
I wanted to make (a == 1 && a == 2 && a == 3) true in Java
I tried to make a login function in Java
I tried to make a client of RESAS-API in Java
I did Java to make (a == 1 && a == 2 && a == 3) always true
I tried to make a talk application in Java using AI "A3RT"
How to create a Java environment in just 3 seconds
I tried to create a Clova skill in Java
I created a PDF in Java.
How to make a Java container
[Beginner] I made a program to sell cakes in Java
I want to make a list with kotlin and java!
I want to make a function with kotlin and java!
Even in Java, I want to output true with a == 1 && a == 2 && a == 3
I tried to convert a string to a LocalDate type in Java
How to make a Java array
I wanted to think I understood Elm's custom types in Java
[Java] I tried to make a maze by the digging method ♪
How to make a Java calendar Summary
Easy to make Slack Bot in Java
I just wanted to logrotate with log4j 2
How to make a Discord bot (Java)
I tried to make a parent class of a value object in Ruby
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (PowerMockito edition)
[JAVA] Project Euler, I got stuck in Q8, so make a note
I wanted to implement a slide show in a fashionable way with slick.
I want to ForEach an array with a Lambda expression in Java
I made a primality test program in Java
Two ways to start a thread in Java + @
I tried to make Basic authentication with Java
I want to send an email in Java.
How to display a web page in Java
java I tried to break a simple block
Code to escape a JSON string in Java
Try to create a bulletin board in Java
I tried to implement deep learning in Java
I wrote a primality test program in Java
I made a rock-paper-scissors game in Java (CLI)
rsync4j --I want to touch rsync in Java.
I tried to output multiplication table in Java
I tried to create Alexa skill in Java
I wrote a prime factorization program in Java
How to make a follow function in Rails
I tried to break a block with java (1)
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (Javassist second decoction)
[Small story] I tried to make the java ArrayList a little more convenient
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (black magic edition)
Make Blackjack in Java
When I wanted to create a method for Premium Friday, it was already in the Java 8 standard API
Let's create a TODO application in Java 2 I want to create a template with Spring Initializr and make a Hello world
Make "I'm not a robot" in Java EE (Jakarta EE)
I want to do something like "cls" in Java
I tried to implement Firebase push notification in Java
I want to use ES2015 in Java too! → (´ ・ ω ・ `)
# 2 [Note] I tried to calculate multiplication tables in Java.
[Personal memo] Make a simple deep copy in Java
How to create a data URI (base64) in Java
I want to define a function in Rails Console
What I learned when building a server in Java
How to convert A to a and a to A using AND and OR in Java
How to convert a file to a byte array in Java