Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/thomasnield/rxkotlinfx

Kotlin extensions to the RxJavaFX framework
https://github.com/thomasnield/rxkotlinfx

interoperability javafx kotlin kotlin-extensions reactivex rxjava tornadofx

Last synced: 9 days ago
JSON representation

Kotlin extensions to the RxJavaFX framework

Awesome Lists containing this project

README

        

![](https://camo.githubusercontent.com/78eeb41c5378ae03cf0d23e71c3e0c9e61b0d984/687474703a2f2f692e696d6775722e636f6d2f7837726d586b652e706e67)

# UNSUPPORTED, PLEASE FORK AND SUPPORT

# RxKotlinFX
Kotlin extensions to the [RxJavaFX](https://github.com/ReactiveX/RxJavaFX) library. This framework works especially well with [TornadoFX](https://github.com/edvin/tornadofx). See a fully functional demo [here!](https://github.com/thomasnield/rxkotlinfx-tornadofx-demo)

## Documentation
[Learning RxJava with JavaFX](https://www.gitbook.com/book/thomasnield/rxjavafx-guide/details)

## Binaries

Binaries and dependency information for Maven, Ivy, Gradle and others can be found at [http://search.maven.org](http://search.maven.org/#search%7Cga%7C1%7Cio.reactivex.rxjavafx).

Example for Maven:

```xml

com.github.thomasnield
rxkotlinfx
x.y.z

```

Gradle:

```groovy
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](https://github.com/edvin/tornadofx) and [RxKotlin](https://github.com/ReactiveX/RxKotlin). Please make sure no extension naming conventions conflict with these two other libraries :)

## Features

RxKotlinFX is the convergence of interoperability between [RxJava](https://github.com/ReactiveX/RxJava), [JavaFX](http://docs.oracle.com/javase/8/javase-clienttechnologies.htm), and [Kotlin](https://kotlinlang.org/).

![](http://i.imgur.com/Bhh5CX4.png)

RxKotlinFX contains Kotlin extensions to [RxJavaFX](https://github.com/ReactiveX/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](https://github.com/edvin/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](https://github.com/ReactiveX/RxJavaFX) static factories as extension functions.

|Target Type|Extension Function|Description|
|---|---|---
|Observable<T>|toBinding()|Subscribes the `Observable` to a JavaFX `Binding` implementation. Calling `dispose()` will unsubscribe from the `Observable`
|Observable<T>|toLazyBinding()|Subscribes the `Observable` to a lazy JavaFX `Binding` implementation, delaying subscription until a value is needed. Calling `dispose()` will unsubscribe from the `Observable`
|Property<T>|bind(observable: Observable<T>)|Binds a `Property` to the emissions of an `Observable`, 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` into an RxJava `Observable` that emits the latest value
|ObservableValue<T>|toObservableChanges()|Turns a JavaFX `ObservableValue` into an RxJava `Observable>` that emits the old value and new value as a pair
|Dialog<T>|toObservable<T>|Returns an `Observable` that emits the given result of `Dialog`. 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>` that emits the entire `ObservableList` every time it is modified.
|ObservableList<T>|additions()|Creates an `Observable` emitting `T` items that were added to the `ObservableList`
|ObservableList<T>|removals()|Creates an `Observable` emitting `T` items that were removed from the `ObservableList`
|ObservableList<T>|updates()|Creates an `Observable` emitting `T` items whose specified properties were updated in the `ObservableList`
|ObservableList<T>|changes()|Creates an `Observable>` emitting `ListChange` items, which pairs each item with an `ADDED`, `REMOVED`, or `UPDATED` flag
|ObservableList<T>|distinctChanges()|Creates an `Observable>` emitting *distinct* `ListChange` 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>` emitting *distinct* `ListChange` 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>` emitting *distinct* `ListChange` 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
```kotlin
val myButton = Button("Press Me")
val subscription = myButton.actionEvents().subscribe { println("Pressed!") }
```
##### Creating a Reactive Binding
```kotlin
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
```kotlin
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

```kotlin
val observableList = FXCollections.observableArrayList()

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

```kotlin
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
```kotlin
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`.

```kotlin
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](https://github.com/edvin/tornadofx/blob/master/src/main/java/tornadofx/Nodes.kt). For example, helpful `Observable` extension functions and properties can be added to `TableView` and `ListView`, such as selection events.

```kotlin
val tableView: TableView = ...
val selections: Observable = tableView.itemSelections
val rowIndexSelections: Observable = tableView.rowIndexSelections
```

Check releases as well the [Nodes code file](https://github.com/thomasnield/RxKotlinFX/blob/master/src/main/kotlin/rx/javafx/kt/Nodes.kt) 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](https://github.com/thomasnield/RxKotlinFx/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

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.