Skip to content

Commit 2609e9c

Browse files
committed
Update README with documentation
1 parent daedeb1 commit 2609e9c

File tree

1 file changed

+145
-1
lines changed

1 file changed

+145
-1
lines changed

README.md

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Learn more about RxJava on the <a href="https://github.com/ReactiveX/RxJava/wiki">Wiki Home</a> and the <a href="http://techblog.netflix.com/2013/02/rxjava-netflix-api.html">Netflix TechBlog post</a> where RxJava was introduced.
44

5+
RxJavaFX is a simple API to convert JavaFX events into RxJava Observables. It also has a scheduler to safely move emissions to the JavaFX Event Dispatch Thread.
6+
57
## Master Build Status
68

79
<a href='https://travis-ci.org/ReactiveX/RxJavaFX/builds'><img src='https://travis-ci.org/ReactiveX/RxJavaFX.svg?branch=0.x'></a>
@@ -26,7 +28,15 @@ Example for Maven:
2628
<version>x.y.z</version>
2729
</dependency>
2830
```
29-
and for Ivy:
31+
32+
Gradle:
33+
34+
```groovy
35+
dependencies {
36+
compile 'io.reactivex:rxjavafx:x.y.z'
37+
}
38+
```
39+
Ivy:
3040

3141
```xml
3242
<dependency org="io.reactivex" name="rxjavafx" rev="x.y.z" />
@@ -42,6 +52,140 @@ $ cd RxJavaFX/
4252
$ ./gradlew build
4353
```
4454

55+
## Features
56+
57+
RxJava has two sets of features:
58+
- A scheduler for the JavaFX dispatch thread
59+
- Factories to turn `Node` events and `ObservableValue` changes into an RxJava `Observable`.
60+
61+
###Node Events
62+
You can get event emissions by calling `JavaFxObservable.fromNodeEvents()` and pass the JavaFX `Node` and the `EventType` you are interested in. This will return an RxJava `Observable`.
63+
```
64+
Button incrementBttn = new Button("Increment");
65+
66+
Observable<ActionEvent> bttnEvents =
67+
JavaFxObservable.fromNodeEvents(incrementBttn, ActionEvent.ACTION);
68+
```
69+
70+
71+
### ObservableValue Changes
72+
Not to be confused with the RxJava `Observable`, the JavaFX `ObservableValue` can be converted into an RxJava `Observable` that emits the initial value and all value changes.
73+
74+
```
75+
TextField textInput = new TextField();
76+
77+
Observable<String> textInputs =
78+
JavaFxObservable.fromObservableValue(textInput.textProperty());
79+
```
80+
81+
Note that many Nodes in JavaFX will have an initial value, which sometimes can be `null`, and you might consider using RxJava's `skip()` operator to ignore this initial value.
82+
83+
### JavaFX Scheduler
84+
85+
When you update any JavaFX control, it must be done on the JavaFX Event Dispatch Thread. Fortunately, the `JavaFxScheduler` makes it trivial to take work off the JavaFX thread and put it back when the results are ready. Below we can use the `observeOn()` to pass text value emissions to a computation thread where the text will be flipped. Then we can pass `JavaFxScheduler.getInstance()` to another `observeOn()` afterwards to put it back on the JavaFX thread. From there it will update the `flippedTextLabel`.
86+
87+
```
88+
TextField textInput = new TextField();
89+
Label fippedTextLabel = new Label();
90+
91+
Observable<String> textInputs =
92+
JavaFxObservable.fromObservableValue(textInput.textProperty());
93+
94+
sub2 = textInputs.observeOn(Schedulers.computation())
95+
.map(s -> new StringBuilder(s).reverse().toString())
96+
.observeOn(JavaFxScheduler.getInstance())
97+
.subscribe(fippedTextLabel::setText);
98+
```
99+
100+
##Differences from ReactFX
101+
[ReactFX](https://github.com/TomasMikula/ReactFX) is a popular API to implement reactive patterns with JavaFX using the `EventStream`. However, RxJava uses an `Observable` and the two are not (directly) compatible with each other.
102+
103+
Although ReactFX has some asynchronous operators like `threadBridge`, ReactFX emphasizes *synchronous* behavior. This means it encourages keeping events on the JavaFX thread. RxJavaFX, which fully embraces RxJava and *asynchronous* design, can switch between threads and schedulers with ease. As long as subscriptions affecting the UI are observed on the JavaFX thread, you can leverage the powerful operators and libraries of RxJava safely.
104+
105+
If you are heavily dependent on RxJava, asynchronous processing, or do not want your entire reactive codebase to be UI-focused, you will probably want to use RxJavaFX.
106+
107+
## Comprehensive Example
108+
```
109+
package rx.schedulers;
110+
111+
import javafx.application.Application;
112+
import javafx.event.ActionEvent;
113+
import javafx.scene.Scene;
114+
import javafx.scene.control.Button;
115+
import javafx.scene.control.Label;
116+
import javafx.scene.control.TextField;
117+
import javafx.scene.layout.GridPane;
118+
import javafx.stage.Stage;
119+
import rx.Observable;
120+
import rx.Subscription;
121+
import rx.observables.JavaFxObservable;
122+
123+
public class RxJavaFXTest extends Application {
124+
125+
private final Button incrementBttn;
126+
private final Label incrementLabel;
127+
private final Subscription sub1;
128+
129+
private final TextField textInput;
130+
private final Label fippedTextLabel;
131+
private final Subscription sub2;
132+
133+
public RxJavaFXTest() {
134+
135+
//initialize increment demo
136+
incrementBttn = new Button("Increment");
137+
incrementLabel = new Label("");
138+
139+
Observable<ActionEvent> bttnEvents =
140+
JavaFxObservable.fromNodeEvents(incrementBttn, ActionEvent.ACTION);
141+
142+
sub1 = bttnEvents.map(e -> 1).scan(0,(x,y) -> x + y)
143+
.map(Object::toString)
144+
.subscribe(incrementLabel::setText);
145+
146+
//initialize text flipper
147+
textInput = new TextField();
148+
fippedTextLabel = new Label();
149+
150+
Observable<String> textInputs =
151+
JavaFxObservable.fromObservableValue(textInput.textProperty());
152+
153+
sub2 = textInputs.observeOn(Schedulers.computation())
154+
.map(s -> new StringBuilder(s).reverse().toString())
155+
.observeOn(JavaFxScheduler.getInstance())
156+
.subscribe(fippedTextLabel::setText);
157+
}
158+
159+
@Override
160+
public void start(Stage primaryStage) throws Exception {
161+
162+
GridPane gridPane = new GridPane();
163+
164+
gridPane.setHgap(10);
165+
gridPane.setVgap(10);
166+
167+
gridPane.add(incrementBttn,0,0);
168+
gridPane.add(incrementLabel,1,0);
169+
170+
gridPane.add(textInput,0,1);
171+
gridPane.add(fippedTextLabel, 1,1);
172+
173+
Scene scene = new Scene(gridPane);
174+
primaryStage.setWidth(265);
175+
primaryStage.setScene(scene);
176+
primaryStage.show();
177+
}
178+
179+
@Override
180+
public void stop() throws Exception {
181+
super.stop();
182+
183+
sub1.unsubscribe();
184+
sub2.unsubscribe();
185+
}
186+
}
187+
```
188+
45189
## Bugs and Feedback
46190

47191
For bugs, questions and discussions please use the [Github Issues](https://github.com/ReactiveX/RxJavaFX/issues).

0 commit comments

Comments
 (0)