Reactive JavaFX Event Handling

Overview

ReactorFX

Build Status codecov GitHub license GitHub forks GitHub issues Maven Central

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

Comments
  • Allow users to get `Change` object when subscribing to `Observable*` collections

    Allow users to get `Change` object when subscribing to `Observable*` collections

    Currently, this library consumes the most important information about the changes that happened in the underlying library

    For example, if I have a dynamic tree whose children can be added & removed dynamically & I want to expose this information to a TreeView, each node needs to know what changes happened to the child ObservableLists & in what position. This position information can never be accessed because the library swallows this information & only emits a subset of the this important information

    For eg., for ObservableList currently I can only get

    1. A new ObservableList via Flux<ObservableList<T>> from(ObservableList<T> source)
    2. Only the added elements via Flux<T> fromAdditionsOf(ObservableList<T> source)
    3. Only removed elements via Flux<T> fromRemovalsOf(ObservableList<T> source)

    Instead the user should get the full power of underlying *Change (ListChangeListener.Change incase of ObservableList) objects. This way user will know what happened & most importantly where in the underlying child Observable*

    This has to be applied to every Observable* collection as the library should never hinder the user from getting the underlying raw information if the user needs it as my above example demonstrates it

    opened by thekalinga 8
  • Fixes #5 (Breaking Change)

    Fixes #5 (Breaking Change)

    I have added support for cascading the underlying raw changes to the subscriber so that he can deal with the raw information to fulfill his complex requirements

    Changes

    1. Now all the raw change events gets pushed to the subscriber for all observable collections when user uses Flux.fromChangesOf
    2. Added a new ArrayChange that encapsulates the underlying paramaters in the ArrayChangeListener.onChanged(T observableArray, boolean sizeChanged, int from, int to); method
    3. Renamed existing Flux.fromChangesOf(ObservableIntegerArray source) to Flux.fromChangedSubArrayOf(ObservableIntegerArray source) as we have a new method with the same name Flux.fromChangesOf that publishes ArrayChange events. This is done to keep this method name consistent with all other Observable* Collections
    4. Added corresponding unit tests
    5. Updated .gitignore. Most importantly add ignores for the junk most java IDEs produce. Also removed gradle.properties from this file as project level gradle.properties should not contain any sensitive information & is useful to set project level properties. If there are any sensitive properties, we should use <user home>/gradle.properties instead

    Since item 3 in the above list a breaking change, I have updated version to 2.0.0

    opened by thekalinga 2
  • Missing 's' in dependency for gradle ;-)

    Missing 's' in dependency for gradle ;-)

    Dear shadskii,

    thanks a lot for this great tool! I just discovered a minor thing: in your README.md there is a missing 's' in the group-id:

    compile "com.github.shadkii:reactorfx:1.8.0" //Java 8

    ... I was just struggling a bit, because I was simply copying this line ;-) Greetings

    opened by kaifox 1
  • discution

    discution

    hi

    i have a simple senaio: i have a loop with (1000 iteration) and just i want to launch this loop aync, son i use jfxdialog, i launch this senaio in Task, onrunning event i show my jfxdialog and onsuccess or onfaild i close it, i see that jfxdialog is show after loop terminate !!! however i show it in onrunning event (normaly it show before loop start) , any explanation please

    opened by halimpuckjava 1
  • Possibly wrong url in pom

    Possibly wrong url in pom

    Hi Just to let you know, this points to another project, in case this is not intended to be :)

    https://github.com/shadskii/ReactorFX/blob/6758501cce4ea7c794ab1391c7f0706d0c3e5f15/build.gradle#L48

    opened by andreacalia 1
  • Scheduler naming convention.

    Scheduler naming convention.

    In the class FxSchedulers, recommend renaming the function platform to fxThread. It will read better when used in a static import and will likely hold meaning even if you change the the internal implementation.

    opened by masterav10 1
Owner
Jake
Web Developer - Vue.js
Jake
Reactive event streams, observable values and more for JavaFX.

ReactFX ReactFX is an exploration of (functional) reactive programming techniques for JavaFX. These techniques usually result in more concise code, le

Tomas Mikula 360 Dec 28, 2022
Functional Reactive Programming (FRP) for JavaFX

ReduxFX Functional Reactive Programming (FRP) for JavaFX ReduxFX in 1 minute ReduxFX is a set of libraries that enable you to use functional reactive

Michael Heinrichs 108 Oct 16, 2022
Composable event handlers and skin scaffolding for JavaFX controls.

This project is no longer being maintained. See this issue for more details. WellBehavedFX This project provides a better mechanism for defining and o

null 52 Oct 9, 2022
Tray Icon implementation for JavaFX applications. Say goodbye to using AWT's SystemTray icon, instead use a JavaFX Tray Icon.

FXTrayIcon Library intended for use in JavaFX applications that makes adding a System Tray icon easier. The FXTrayIcon class handles all the messy AWT

Dustin Redmond 248 Dec 30, 2022
Lib-Tile is a multi Maven project written in JavaFX and NetBeans IDE 8 and provides the functionalities to use and handle easily Tiles in your JavaFX application.

Lib-Tile Intention Lib-Tile is a multi Maven project written in JavaFX and NetBeans IDE and provides the functionalities to use and handle easily Tile

Peter Rogge 13 Apr 13, 2022
DataFX - is a JavaFX frameworks that provides additional features to create MVC based applications in JavaFX by providing routing and a context for CDI.

What you’ve stumbled upon here is a project that intends to make retrieving, massaging, populating, viewing, and editing data in JavaFX UI controls ea

Guigarage 110 Dec 29, 2022
Event-driven trigger + recording system for FFXIV

Triggevent Fully event driven trigger + overlay system for FFXIV. Makes triggers easier to develop and test. Allows triggers to have custom configurat

null 63 Dec 28, 2022
This app displays the perceived strength of a single earthquake event based on the DYFI indicator.

This app displays the perceived strength of a single earthquake event based on the DYFI indicator. Used in a Udacity course in the Android Basics Nanodegree.

Ezaz Ahammad 1 Jan 23, 2022
Collection of Binding helpers for JavaFX(8)

Advanced-Bindings for JavaFX (8) advanced-bindings is a collection of useful helpers and custom binding implementations to simplify the development of

Manuel Mauky 63 Nov 19, 2022
Docking framework for JavaFX platform

Docking framework for JavaFX platform AnchorFX is a gratis and open source library for JavaFX to create graphical interfaces with docking features Anc

Alessio Vinerbi 197 Oct 15, 2022
A library of +70 ready-to-use animations for JavaFX

AnimateFX A library of ready-to-use animations for JavaFX Features: Custom animations Custom interpolators Play/Stop animation Play an animation after

Loïc Sculier 366 Jan 5, 2023
BootstrapFX: Bootstrap for JavaFX

BootstrapFX BootstrapFX is a partial port of Twitter Bootstrap for JavaFX. It mainly provides a CSS stylesheet that closely resembles the original whi

Kordamp 810 Dec 28, 2022
A Java framework for creating sophisticated calendar views (JavaFX 8, 9, 10, and 11)

CalendarFX A Java framework for creating sophisticated calendar views based on JavaFX. A detailed developer manual can be found online: CalendarFX 8 D

DLSC Software & Consulting GmbH 660 Jan 6, 2023
Allow runtime modification of JavaFX CSS

cssfx ⚠ WARNING ⚠ In version 11.3.0 we have relocated & refactored the project. maven groupId has been changed to fr.brouillard.oss java module name h

Matthieu Brouillard 134 Jan 2, 2023
A JavaFX UI framework to create fully customized undecorated windows

CustomStage A JavaFX undecorated stage which can fully be customized Donations If this project is helpful to you and love my work and feel like showin

Oshan Mendis 186 Jan 6, 2023
MDI components for JavaFX

DesktopPaneFX DesktopPaneFX is a JavaFX version of Swing’s JDesktopPane which can be used as a container for individual "child" similar to JInternalFr

Kordamp 58 Sep 23, 2022
Efficient VirtualFlow for JavaFX

Flowless Efficient VirtualFlow for JavaFX. VirtualFlow is a layout container that lays out cells in a vertical or horizontal flow. The main feature of

null 163 Nov 24, 2022
A framework for easily creating forms for a JavaFX UI.

FormsFX Forms for business application made easy. Creating forms in Java has never been this easy! Maven To use this framework as part of your Maven b

DLSC Software & Consulting GmbH 534 Dec 30, 2022
:icecream: iOS frosty/translucent effect to JavaFX

FroXty is JavaFX library which replicates the famous iOS translucent effect with ease. Set-up FroXty can be imported into your project either by downl

Giorgio Garofalo 33 Dec 11, 2022