Search code examples
javajavafxjava-8reactfx

Live mapping of JavaFX ObservableList or ReactFX LiveList


/**
 * An observable analogue of {@code Stream.map}. The output list is updated
 * whenever the input list changes.
 */
public static <T, R> ListBinding<R> map(
    ObservableList<? extends T> list,
    Function<T, ? extends R> mapper
);

I wrote the above JavaFX utility method which creates a live mapping of an ObservableList, updating the mapping any time the source list changes. I later discovered ReactFX and its equivalent LiveList.map:

public interface LiveList {
    default <F> LiveList<F> map(Function<? super E,? extends F> f);
}

Not wanting to reinvent the wheel again, I am now looking for a map function which returns a list of observables and automatically watches those observables. Basically a flatMap for an entire list. For instance, if I had this:

<T, R> ListBinding<R> flatMap(
    ObservableList<? extends T> list,
    Function<T, ObservableValue<? extends R>> mapper
);

Then I could do this:

ObservableList<Button>  buttons;
ObservableList<Integer> widths = flatMap(buttons, Button::widthProperty);

This widths list would grow and shrink if buttons are added or removed, and would be updated if the buttons' widths change.

Does such a function exist in JavaFX or in ReactFX? Or anything similar?


Solution

  • I am not aware of any existing implementation of flatMap for observable lists.

    It is, however, planned for ReactFX 2.0, likely with this signature

    public interface LiveList {
        default <F> LiveList<F> flatMap(Function<? super E,? extends ObservableList<F>> f);
    }
    

    which is more general than what you propose: it maps an element to a list, instead of just a single value.