• Stars
    star
    176
  • Rank 215,733 (Top 5 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created over 8 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Kotlin extensions to the RxJavaFX framework

UNSUPPORTED, PLEASE FORK AND SUPPORT

RxKotlinFX

Kotlin extensions to the RxJavaFX library. This framework works especially well with TornadoFX. See a fully functional demo here!

Documentation

Learning RxJava with JavaFX

Binaries

Binaries and dependency information for Maven, Ivy, Gradle and others can be found at http://search.maven.org.

Example for Maven:

<dependency>
    <groupId>com.github.thomasnield</groupId>
    <artifactId>rxkotlinfx</artifactId>
    <version>x.y.z</version>
</dependency>

Gradle:

repositories {
    mavenCentral()
}
dependencies {
    compile 'com.github.thomasnield:rxkotlinfx:x.y.z'
}

Contributing

Feel free to contribute and help streamline a pragmatic UI stack with Kotlin, RxJava, and JavaFX. Speaking of stacks, this project may be used in conjunction with TornadoFX and RxKotlin. Please make sure no extension naming conventions conflict with these two other libraries :)

Features

RxKotlinFX is the convergence of interoperability between RxJava, JavaFX, and Kotlin.

RxKotlinFX contains Kotlin extensions to RxJavaFX as well as additional Observable operators specific to JavaFX. It also is in exporatory stages to add helpful Node extension functions that return Observables. This exploration is inspired by the JavaFX/Kotlin interop project TornadoFX. Where TornadoFX handles layouts, node extensions, DI, and other JavaFX/Kotlin interoperations, this library will seek to integrate RxJava with JavaFX in the same spirit using Kotlin. The vision is to add useful extensions that put Observable streams as properties and functions on JavaFX components, especially where ObservableValue properties are not readily available.

RxJavaFX Extensions

The core API implements RxJavaFX static factories as extension functions.

Target Type Extension Function Description
Observable<T> toBinding() Subscribes the Observable<T> to a JavaFX Binding implementation. Calling dispose() will unsubscribe from the Observable<T>
Observable<T> toLazyBinding() Subscribes the Observable<T> to a lazy JavaFX Binding implementation, delaying subscription until a value is needed. Calling dispose() will unsubscribe from the Observable<T>
Property<T> bind(observable: Observable<T>) Binds a Property<T> to the emissions of an Observable<T>, and returns the Binding
Binding<T> addTo(compositeBinding: CompositeBinding) Adds the Binding to a CompositeBinding, and returns the Binding
ObservableValue<T> toObservable() Turns a JavaFX ObservableValue<T> into an RxJava Observable<T> that emits the latest value
ObservableValue<T> toObservableChanges() Turns a JavaFX ObservableValue<T> into an RxJava Observable<Change<T>> that emits the old value and new value as a pair
Dialog<T> toObservable<T> Returns an Observable<T> that emits the given result of Dialog<T>. Will be empty if no response.
Node, Window, Scene events(eventType: EventType) Creates an Observable emitting events of the given EventType
Node, MenuItem, ContextMenu actionEvents() Creates an Observable that emits an ActionEvent every time one occurs
ObservableList<T> onChangedObservable() Returns an Observable<ObservableList<T>> that emits the entire ObservableList<T> every time it is modified.
ObservableList<T> additions() Creates an Observable<T> emitting T items that were added to the ObservableList<T>
ObservableList<T> removals() Creates an Observable<T> emitting T items that were removed from the ObservableList<T>
ObservableList<T> updates() Creates an Observable<T> emitting T items whose specified properties were updated in the ObservableList<T>
ObservableList<T> changes() Creates an Observable<ListChange<T>> emitting ListChange<T> items, which pairs each item with an ADDED, REMOVED, or UPDATED flag
ObservableList<T> distinctChanges() Creates an Observable<ListChange<T>> emitting distinct ListChange<T> items. It will only emit the first ADDED item T and not emit dupes, and will only emit the REMOVED item T when no more dupes exist
ObservableList<T> distinctChanges(mapper: (T) -> R) Creates an Observable<ListChange<T>> emitting distinct ListChange<T> items based off the mapper's definition of a distinct value R. It will only emit the first ADDED item T and not emit dupes, and will only emit the REMOVED item T when no more dupes exist
ObservableList<T> distinctMappingChanges(mapper: (T) -> R) Creates an Observable<ListChange<R>> emitting distinct ListChange<R> mappings based off the mapper's definition of a distinct value R. It will only emit the first ADDED item R and not emit dupes, and will only emit the REMOVED item R when no more dupes exist
Observable of Button ActionEvents
val myButton = Button("Press Me")
val subscription = myButton.actionEvents().subscribe { println("Pressed!") } 
Creating a Reactive Binding
val myButton = Button("Press Me")

val countBinding = myButton.actionEvents().map { 1 }
    .scan(0, { x,y -> x + y })
    .map { it.toString() }
    .toBinding()
    
val myLabel = Label()
myLabel.textProperty().bind(countBinding)
Observable of ObservableList Events
val items = FXCollections.observableArrayList("Alpha", "Beta", "Gamma")

val changes = items.changes()

changes.filter { it.flag == Flag.ADDED }
        .map { it.value }
        .subscribe { println("ADDED $it") }

items.add("Delta")
items.add("Epsilon")
OUTPUT
ADDED Delta
ADDED Epsilon
Turning an ObservableList into a Hot Concatenation
val observableList = FXCollections.observableArrayList<String>()

observableList.onChangedObservable()
        .flatMap {
            it.toObservable().map { it.length }
                    .map { it.toString() }
                    .reduce { s1,s2 -> s1 + "|"  + s2  }
        }
        .subscribe { println(it) }

observableList.setAll("Alpha", "Beta", "Gamma")
observableList.add("Delta")
observableList.add("Epsilon")
observableList.remove("Alpha")
OUTPUT
5|4|5
5|4|5|5
5|4|5|5|7
4|5|5|7
Using a Dialog or Alert
val dialog = Alert(AlertType.CONFIRMATION, "Are you sure you want to continue?")

dialog.toObservable().filter { it == ButtonType.YES }
	.subscribe { println("You pressed YES") } 
Using and Disposing CompositeBinding
val binding1: Binding = ...
val binding2: Binding = ... 

//adding one at a time
val bindings = CompositeBinding()
val bindings += binding1
val bindings += binding2

//or all at once
val bindings = CompositeBinding(binding1,binding2)

//do stuff, then dispose Bindings
bindings.dispose()

Operators

RxKotlinFX has a growing list of operators placed as extension functions onto Observable that aid interoperability with JavaFX.

Operator Description
observeOnFx() Schedules the emissions to be observed on the JavaFX thread
subscribeOnFx() Schedules the source Observable to emit items on the JavaFX thread
doOnNextFx() Executes the specified action on the FX thread for each emission
doOnErrorFx() Executes the specified action on the FX thread when an error is emitted
doOnCompleteFx() Executes the specified action on the FX thread when the Observable calls onComplete()
doOnSubscribeFx() Executes the specified action on the FX thread when the Observable is first subscribed
doOnTerminateFx() Executes the specified action on the FX thread when the Observable calls onComplete() or onError()
doOnDisposeFx() Executes the specified action on the FX thread when the Observable is unsubscribed
doOnNextCount() Executes the specified action with the cumulative count of emissions for that emission
doOnErrorCount() Executes the specified action with the cumulative count of emissions when an error is emitted
doOnCompleteCount() Executes the specified action with the total emission count when onComplete() is called
doOnNextCountFx() Same as doOnNextCount() except action is executed on FX thread
doOnErrorCountFx() Same as doOnErrorCount() except action is executed on FX thread
doOnCompleteCountFx() Same as doOnCompleteCount() except action is executed on FX thread

The doOnXXXCount() operators are especially helpful for providing a status update of how many items have been "processed" by an Observable.

val source = Observable.range(1,1000)
val processedCountLabel = Label()

source.map { it * 10 }
     .doOnNextFx { processedCountLabel.text = "Processed $it items" }
     .subsribe { doSomethingWith(it) }

Control Extensions

The rest of the project will likely add convenient extension functions to emit events as Observable values, much like the TornadoFX project has done. For example, helpful Observable extension functions and properties can be added to TableView and ListView, such as selection events.

val tableView: TableView<MyItem> = ...
val selections: Observable<MyItem> = tableView.itemSelections
val rowIndexSelections: Observable<Int> = tableView.rowIndexSelections

Check releases as well the Nodes code file to see a list of available extensions. Feel free to contribute if you see any missing.

Bugs and Feedback

For bugs, questions and discussions please use the Github Issues.

LICENSE

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

More Repositories

1

oreilly_getting_started_with_sql

Database files for the O'Reilly book "Getting Started with SQL: A hands on approach for beginners" http://goo.gl/z3zG54
333
star
2

oreilly_machine_learning_from_scratch

Resources for the O'Reilly Online Training "Machine Learning from Scratch"
Python
208
star
3

oreilly_intermediate_sql_for_data

Resources for the O'Reilly Online Training "Intermediate SQL For Data Analysis"
177
star
4

oreilly_math_fundamentals_data_science

Python
156
star
5

oreilly_sql_fundamentals_for_data

Resources for O'Reilly "SQL Fundamentals for Data" online training
153
star
6

oreilly_reactive_python_for_data

Resources for the O'Reilly online video "Reactive Python for Data"
Python
106
star
7

machine-learning-demo-data

100
star
8

oreilly_intro_to_mathematical_optimization

O'Reilly online training "Intro to Mathematical Optimization"
Python
89
star
9

kotlin_math_cheatsheet

A cheatsheet for translation math expressions to Kotlin
82
star
10

rxkotlinfx-tornadofx-demo

A demo application demonstrating TornadoFX and Rx usage
Kotlin
76
star
11

traveling_salesman_demo

A Kotlin implementation of the TSP problem, with TornadoFX Visualization
Kotlin
60
star
12

kotlin-sudoku-solver

A suduko game solver written in Kotlin
Kotlin
56
star
13

kotlin_simple_neural_network

A simple neural network application built in Kotlin
Kotlin
51
star
14

oreilly_programming_with_sql

Java
37
star
15

classroom-scheduling-demo

A branch-and-bound solver to create classroom schedules
Kotlin
36
star
16

DirtyFX

Dirty state-tracking properties and collections for JavaFX
Kotlin
31
star
17

rxkotlin-jdbc

Fluent RxJava JDBC extension functions for Kotlin
Kotlin
28
star
18

bayes_user_input_prediction

Demonstration of using Naive Bayes to predict user inputs with Kotlin 1.2 std-lib
Kotlin
27
star
19

rxkotlin-poc

Experimental Rx implementation in Kotlin
Kotlin
23
star
20

kotlinconf-datascience-talk

Slides, notes, and code for KotlinConf talk on Data Science
18
star
21

oreilly_essential_math_for_data_science_book

Book code for "Essential Math for Data Science"
Python
18
star
22

kotlin-spark-test

Simple demonstration using Kotlin with Spark
Kotlin
17
star
23

oreilly-probability-from-scratch

Python
15
star
24

oreilly_deep_learning_beginners

Python
15
star
25

kotlinconf-2018-mathematical-modeling

Rescoures for "Mathematical Modeling with Kotlin" talk at KotlinConf 2018
15
star
26

idea_eclipse_dark_theme

An Intellij IDEA port of the amazing Eclipse Dark theme
12
star
27

anaconda_intro_to_machine_learning

Jupyter Notebook
11
star
28

oreilly_kotlin_for_data_science

Notes, slides, and contents for the O'Reilly videos using Kotlin for Data Science
Kotlin
11
star
29

customer-wait-queue-simulation

Using poisson distribution to optimize/simulate staffing count decisions to minimize wait times
Kotlin
11
star
30

traveling_salesman_plotter

A Traveling Salesman Problem plotter built in Kotlin/TornadoFX
Kotlin
10
star
31

anaconda_data_cleaning_pandas

Jupyter Notebook
9
star
32

kotlin-collection-extras

Useful extensions for kotlin collections
Kotlin
9
star
33

rxkotlin-extras

Kotlin Extensions to the rxjava-extras library
Kotlin
9
star
34

sql-injection-demo

A simple username/password login application to demonstrate SQL injection
Kotlin
9
star
35

3mds

Source code for 3-Minute Data Science Videos
Python
8
star
36

bayes_email_spam

Experimenting with Bayes and Email Spam Categorization
Kotlin
7
star
37

ai-appraisal-and-hype-articles

Articles and resources that see past AI hype and focus on practicality and realistic expectations
6
star
38

anaconda_intro_to_sql

Jupyter Notebook
5
star
39

ojalgo_abstract_examples

Kotlin
4
star
40

kotlin_linear_regression

Kotlin
4
star
41

data_science_from_scratch_rx

RxPy versions of code from the O'Reilly book "Data Science from Scratch"
Python
4
star
42

code_of_conduct_dont_be_an_idiot

A practical, simple code of conduct you can use in your own projects
4
star
43

katacoda-scenarios

Katacoda Scenarios
Shell
3
star
44

ChicagoKUG_Many_Types_of_AI

https://www.meetup.com/Chicago-Kotlin/events/260487964/
3
star
45

3mds-lib

Library for supporting my Manim animations and 3MDS
Python
3
star
46

thomasnield_odsc2023

Python
3
star
47

JavaMug2019_Many_Types_of_AI

3
star
48

java_developers_dallas_talk_2018

Mathematical modeling on the JVM, talk resources and slides
3
star
49

continuous-optimization-example

Kotlin
2
star
50

mathematical-optimization-examples

Kotlin
2
star
51

tornadofx-live-examples

Kotlin
2
star
52

blog_articles

2
star
53

tom-sync

A Java 8 library with helpful concurrency tools, inlcuding lazy initializers and synchronizers
Java
2
star
54

3b1b_pycharm_theme

A 3Blue1Brown-inspired theme for PyCharm
2
star
55

anaconda_statistics_hypothesis_testing

Jupyter Notebook
2
star
56

numky

Idiomatic linear algebra for Kotlin using KMath
Kotlin
2
star
57

packt_learning_rxjava

Code examples for the Packt book "Learning RxJava"
Java
2
star
58

oreilly-strata-london-2020-ml-spark-sklearn

Python
1
star
59

bdd_chicago_many_types_of_ai

1
star
60

gradle_eclipse_multiproject_bug

This project was created to help the Eclipse Gradle team debug an issue with multiprojects http://goo.gl/vsBxiB
Java
1
star
61

ahk_scripts

AutoHotkey
1
star
62

bayes_price_war

Kotlin
1
star
63

fractional-reserve-simulation

Macroeconomic model for fractional reserve modeling
Kotlin
1
star
64

anaconda_probability_fundamentals

Jupyter Notebook
1
star
65

auto-driving-simulation

Kotlin
1
star
66

anaconda_linear_algebra

Jupyter Notebook
1
star
67

anaconda_ncaa_data_cleaning

For the live event: https://learning.anaconda.cloud/cleaning-and-preparing-data-with-pandas
1
star
68

rxjavafx-guide

1
star
69

oreilly_data_engineering_fundamentals

1
star
70

oreilly_foo_many_types_of_ai_demo

Kotlin
1
star