ReactorFX
This lightweight convenience library allows for simple integration between Project Reactor and JavaFX. ReactorFX provides fluent factories to create Flux
for the propagation of events from JavaFX Controls, Collections, and Observables.
Usage
ReactorFX currently supports Java8+
compile "com.github.shadskii:reactorfx:2.0.0" //Java 8
Events
In JavaFX user interactions are propagated through Events. These Events
can be emitted from Node
, Scene
, MenuItem
, and Window
. ReactorFX provides simple, fluent, and consistent factories for the creation of Fluxes from these sources. You can create Fluxes by using FxFlux.from()
and passing the source and EventType
to listen to. FxFlux.from()
provides overloaded factories such that omitting the EventType
will result in a Flux
that listens for ActionEvents
.
Events From A Control
Button btn = new Button("Hey I'm A Button!");
Flux<Event> buttonEvents = FxFlux.from(btn)
.subscribeOn(FxSchedulers.fxThread())
.publishOn(anotherScheduler);
Events From A Scene
Scene scene = new Scene(new Label("Hey I'm A Label!"));
Flux<MouseEvent> mouseEvents = FxFlux.from(scene, MouseEvent.MOUSE_CLICKED)
.subscribeOn(FxSchedulers.fxThread())
.publishOn(anotherScheduler);
Events From A Window
Flux<WindowEvent> windowEvents = FxFlux.from(primaryStage, WindowEvent.WINDOW_HIDING)
.subscribeOn(FxSchedulers.fxThread())
.publishOn(anotherScheduler);
ObservableValue
Updates of any JavaFX ObservableValue
can be emitted onto a Flux
by using the factory FxFlux.from(ObservableValue<T> observableValue)
which creates a Flux
that emits the initial value of the observable followed by any subsequent changes to the Observable. Often the initial value of an ObservableValue
is null. The reactive streams specification disallows null values in a sequence so these null values are not emitted.
SimpleObjectProperty<String> observable = new SimpleObjectProperty<>();
Flux<String> flux = FxFlux.from(observable);
Changes from an ObservableValue
can also be emitted as a Change
which is a pairing of the old value and the new value. This Flux
can be produced from the factory FxFlux.fromChangesOf(ObservableValue<T> observableValue)
.
SimpleObjectProperty<String> observable = new SimpleObjectProperty<>();
Flux<Change<String>> flux = FxFlux.fromChangesOf(observable)
.filter(change -> "Hello".equals(change.getOldValue()))
.filter(change -> "World".equals(change.getNewValue()));
JavaFX Scheduler
JavaFX controls are required to be updated on the JavaFX Application Thread. FxSchedulers.fxThread()
is a Scheduler that provides a way to easily the JavaFX Application Thread. Using this scheduler makes it possible to listen to JavaFX controls using Reactive Streams.
ProgressBar p1 = new ProgressBar();
Flux.interval(Duration.ofMillis(1000))
.map(l -> l/100.0)
.publishOn(FxSchedulers.fxThread())
.subscribe(p1::setProgress);
JavaFX Collections Support
ReactorFX also provides fluent factories for creating a Flux
from any JavaFX Collection by four overloaded factory methods.
from()
Using this factory will produce a Flux
that emits the argument JavaFX Collection whenever it has been changed.
fromAdditionsOf()
Using this factory produces a Flux
that emits any element added to the argument collection after it has been added.
fromRemovalsOf()
Using this factory produces a Flux
that emits any element removed from the argument collection whenever it has been removed.
fromChangesOf()
Using this factory produces a Flux
that emits a Change
element as soon as any change (add/remove/modify) is performed on the underlying collection. If you want access to the actual underlying event from JavaFx collection, use this
The below factory method is provided for ObservableArray and it emits the changed sub-array of the argument array whenever it has been changed
fromChangedSubArrayOf()
Collections
Licensed under Apache Software License 2.0