<commit_before>= Java MVVM with Swing, RxJava and RxSwing examples
<NAME>
:imagesdir: ./docs
:project-name: Java_MVVM_with_Swing_and_RxJava_Examples
:github-branch: master
:github-user: Petikoch
:bintray-user: petikoch

image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"]
image:https://travis-ci.org/{github-user}/{project-name}.svg?branch={github-branch}["Build Status", link="https://travis-ci.org/{github-user}/{project-name}"]

== Introduction

There are a lot of different architectures for the GUI:
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller[*Model View Controller*],
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter[*Model View Presenter*],
https://en.wikipedia.org/wiki/Model_View_ViewModel[*Model View ViewModel*],
http://martinfowler.com/eaaDev/PresentationModel.html[*PresentationModel*], ...

All of them try more or less

* to decouple the "different things" (widgets, forms, business logic, ...) from each other
* make the "different things" easily testable (unit-testable)
* try to separate presentation from behaviour
* make the View easily "exchangeable" (e.g. replace Swing with JavaFX)
* concentrate the business logic into e.g. the "Model", which "lives longer" (in years) than the often changing GUI technologies
* ...

When you develop a Java Swing GUI in practice, you face the following additional challenges

* how to enforce the proper threading (View elements like JPanel, JButton, ... should be only accessed by AWT-EventDispatchThread)?
* how to keep the View "responsive" by kicking off background actions (-> SwingWorker, new Thread(...), ExecutorService, ...)?
* how to combine the results from multiple asynchronous actions (multiple SwingWorker's, Thread's, Future's, ...) into one result for the View?
* how to implement Undo/Redo, Validation, Exception-Handling, Timeouts, ...?
* how to enforce acyclic relationships between "stuff" to get good (isolated) testability?
* how to deal with backpressure when e.g. the backend is too fast for the frontend and the GUI thread can't keep up?
* how to connect an ActionListener on e.g. a "Cancel" button with a just started SwingWorker and disconnect it after the SwingWorker finished?
* ...

So, which GUI architecture should you choose? What are the benefits and drawbacks in general? And for your current project?
What libraries are available to make "quick progress" and not reinvent the wheel?

These are a lot of questions which are IMO not easily answered for a Java Swing GUI.

=== The idea

One day, I had a deep lock at https://en.wikipedia.org/wiki/Model_View_ViewModel[*MVVM*] and came up with the idea of

* using https://github.com/ReactiveX/RxJava[RxJava]'s http://reactivex.io/documentation/subject.html[Subject] objects as "listenable" value objects for the ViewModel
* https://github.com/ReactiveX/RxSwing[RxSwing] to connect the View widgets (JButton, JTextField, ...) to the ViewModel-Subjects as "data binding"
* https://github.com/ReactiveX/RxJava[RxJava] to react on changes of the ViewModel-Subjects and interact with the Model (backend) -> fluent API for "flows" (aka streams, pipeline)
* use RxJava's http://reactivex.io/documentation/scheduler.html[Scheduler] and the RxSwing https://github.com/ReactiveX/RxSwing/blob/0.x/src/main/java/rx/schedulers/SwingScheduler.java[SwingScheduler] to do the threading

image::Java_MVVM_RxJava_basic_idea.png[]

I started with some small examples for different aspects. The examples were really nice IMO and I'd like to share it with you through this github repo.

== Implementing MVVM using RxJava and RxSwing

First, let's look at the "data flow" in MVVM:

image::MVVMPattern.png[]

* The View interacts with the ViewModel through DataBinding (this means in practise you don't see any method calls, listeners etc in your sourcecode, you just see "binding" code)
* The View doesn't interact with the Model
* The ViewModel interacts with the Model through ordinary Model API call's
* The Model API has some kind of callbacks to push data up to the ViewModel (dashed arrow)

Second, let's look at the dependencies:

image::MVVM_dependencies.png[]

* The View "sees" the ViewModel
* The View "doesn't see" the Model
* The ViewModel "sees" the Model
* The Model "doesn't see" the ViewModel and "doesn't see" the View
* We have acyclic dependencies

==== Basic ideas behind the implementation of the examples here

* Threading
** All the action between View and ViewModel happens on the `SwingScheduler`
** All the action between ViewModel and Model happens "async" on `Schedulers.io()` (= cached thread pool)

* View
** DataBinding
*** We add a little "Binder" fluent API a la https://github.com/canoo/open-dolphin/blob/master/subprojects/shared/src/main/groovy/org/opendolphin/binding/Binder.groovy[open-dolphin's Binder] on top of RxJava
** There is no other code than a) DataBinding code and b) plain GUI structure code in the View (= passive View)
** "Large" View's are composed by combining multiple "small" View's

* ViewModel
** Per View exits a ViewModel
*** The ViewModel represents the structure of the View 1:1
** We use http://reactivex.io/documentation/subject.html[Rx Subject]'s as "fields" in the ViewModel
*** Each subject "field" in the ViewModel corresponds to one widget in the View
*** We use a little prefix for the "field" name like `v2vm_` or `vm2v_` to indicate the flow direction
*** We use the `BehaviorSubject` class for Subject instances, which is a stateful Subject to have the "current" state, an initial state and easy testability
** The ViewModel handles all the "complicated" interaction stuff between View and Model (threading, exception handling, flows, ...)

* Model
** The Model doesn't care about it's presentation and just offers an API
** The Model is therefore fully focused on business logic and data

As you can see, there is no kind of "framework" described here to implement MVVM.
Instead, it's just the combination of standard JDK classes with the RxJava and RxSwing libraries,
together with some additional fluent API code for "nice" DataBinding.

== Examples

The examples start simple and get more and more complicated, adding additional aspects and features.

There is not a "full example" which shows all aspects at the moment, since this is just some code to figure out
how to build MVVM using RxJava and RxSwing. Every example shows just one or more aspects.

Running the examples: +

`./gradlew run -Pexample=<example>, e.g.: ./gradlew run -Pexample=7a`

Scope: +
The *current* examples are all "everything in one process" examples: View, ViewModel and Model run in one process in the same JVM. +
Upcoming examples might include JavaFx, Android, Web and of course some kind of remoting to split "things" across multiple processes.

=== Example 1: Hello World (from the Model)

link:./src/main/java/ch/petikoch/examples/mvvm_rxjava/example1[]

* The Model pushes "hello world's" thru an Observable to the ViewModel (using a computational thread)
* A JLabel in the View is bound to the `vm2v_info` field of the ViewModel
* The `RxViewModel2SwingViewBinder` code does the switch to the `SwingScheduler`<commit_msg>More details for "Running the examples"<commit_after>= Java MVVM with Swing, RxJava and RxSwing examples
<NAME>
:imagesdir: ./docs
:project-name: Java_MVVM_with_Swing_and_RxJava_Examples
:github-branch: master
:github-user: Petikoch
:bintray-user: petikoch

image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"]
image:https://travis-ci.org/{github-user}/{project-name}.svg?branch={github-branch}["Build Status", link="https://travis-ci.org/{github-user}/{project-name}"]

== Introduction

There are a lot of different architectures for the GUI:
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller[*Model View Controller*],
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter[*Model View Presenter*],
https://en.wikipedia.org/wiki/Model_View_ViewModel[*Model View ViewModel*],
http://martinfowler.com/eaaDev/PresentationModel.html[*PresentationModel*], ...

All of them try more or less

* to decouple the "different things" (widgets, forms, business logic, ...) from each other
* make the "different things" easily testable (unit-testable)
* try to separate presentation from behaviour
* make the View easily "exchangeable" (e.g. replace Swing with JavaFX)
* concentrate the business logic into e.g. the "Model", which "lives longer" (in years) than the often changing GUI technologies
* ...

When you develop a Java Swing GUI in practice, you face the following additional challenges

* how to enforce the proper threading (View elements like JPanel, JButton, ... should be only accessed by AWT-EventDispatchThread)?
* how to keep the View "responsive" by kicking off background actions (-> SwingWorker, new Thread(...), ExecutorService, ...)?
* how to combine the results from multiple asynchronous actions (multiple SwingWorker's, Thread's, Future's, ...) into one result for the View?
* how to implement Undo/Redo, Validation, Exception-Handling, Timeouts, ...?
* how to enforce acyclic relationships between "stuff" to get good (isolated) testability?
* how to deal with backpressure when e.g. the backend is too fast for the frontend and the GUI thread can't keep up?
* how to connect an ActionListener on e.g. a "Cancel" button with a just started SwingWorker and disconnect it after the SwingWorker finished?
* ...

So, which GUI architecture should you choose? What are the benefits and drawbacks in general? And for your current project?
What libraries are available to make "quick progress" and not reinvent the wheel?

These are a lot of questions which are IMO not easily answered for a Java Swing GUI.

=== The idea

One day, I had a deep lock at https://en.wikipedia.org/wiki/Model_View_ViewModel[*MVVM*] and came up with the idea of

* using https://github.com/ReactiveX/RxJava[RxJava]'s http://reactivex.io/documentation/subject.html[Subject] objects as "listenable" value objects for the ViewModel
* https://github.com/ReactiveX/RxSwing[RxSwing] to connect the View widgets (JButton, JTextField, ...) to the ViewModel-Subjects as "data binding"
* https://github.com/ReactiveX/RxJava[RxJava] to react on changes of the ViewModel-Subjects and interact with the Model (backend) -> fluent API for "flows" (aka streams, pipeline)
* use RxJava's http://reactivex.io/documentation/scheduler.html[Scheduler] and the RxSwing https://github.com/ReactiveX/RxSwing/blob/0.x/src/main/java/rx/schedulers/SwingScheduler.java[SwingScheduler] to do the threading

image::Java_MVVM_RxJava_basic_idea.png[]

I started with some small examples for different aspects. The examples were really nice IMO and I'd like to share it with you through this github repo.

== Implementing MVVM using RxJava and RxSwing

First, let's look at the "data flow" in MVVM:

image::MVVMPattern.png[]

* The View interacts with the ViewModel through DataBinding (this means in practise you don't see any method calls, listeners etc in your sourcecode, you just see "binding" code)
* The View doesn't interact with the Model
* The ViewModel interacts with the Model through ordinary Model API call's
* The Model API has some kind of callbacks to push data up to the ViewModel (dashed arrow)

Second, let's look at the dependencies:

image::MVVM_dependencies.png[]

* The View "sees" the ViewModel
* The View "doesn't see" the Model
* The ViewModel "sees" the Model
* The Model "doesn't see" the ViewModel and "doesn't see" the View
* We have acyclic dependencies

==== Basic ideas behind the implementation of the examples here

* Threading
** All the action between View and ViewModel happens on the `SwingScheduler`
** All the action between ViewModel and Model happens "async" on `Schedulers.io()` (= cached thread pool)

* View
** DataBinding
*** We add a little "Binder" fluent API a la https://github.com/canoo/open-dolphin/blob/master/subprojects/shared/src/main/groovy/org/opendolphin/binding/Binder.groovy[open-dolphin's Binder] on top of RxJava
** There is no other code than a) DataBinding code and b) plain GUI structure code in the View (= passive View)
** "Large" View's are composed by combining multiple "small" View's

* ViewModel
** Per View exits a ViewModel
*** The ViewModel represents the structure of the View 1:1
** We use http://reactivex.io/documentation/subject.html[Rx Subject]'s as "fields" in the ViewModel
*** Each subject "field" in the ViewModel corresponds to one widget in the View
*** We use a little prefix for the "field" name like `v2vm_` or `vm2v_` to indicate the flow direction
*** We use the `BehaviorSubject` class for Subject instances, which is a stateful Subject to have the "current" state, an initial state and easy testability
** The ViewModel handles all the "complicated" interaction stuff between View and Model (threading, exception handling, flows, ...)

* Model
** The Model doesn't care about it's presentation and just offers an API
** The Model is therefore fully focused on business logic and data

As you can see, there is no kind of "framework" described here to implement MVVM.
Instead, it's just the combination of standard JDK classes with the RxJava and RxSwing libraries,
together with some additional fluent API code for "nice" DataBinding.

== Examples

The examples start simple and get more and more complicated, adding additional aspects and features.

There is not a "full example" which shows all aspects at the moment, since this is just some code to figure out
how to build MVVM using RxJava and RxSwing. Every example shows just one or more aspects.

*Running the examples:* +

Run the main class of each example in your favourite IDE

_or_

Use the gradle-wrapper on your favourite console

`./gradlew run -Pexample=<example>` +
e.g.: +
`./gradlew run -Pexample=7a`

Scope: +
The *current* examples are all "everything in one process" examples: View, ViewModel and Model run in one process in the same JVM. +
Upcoming examples might include JavaFx, Android, Web and of course some kind of remoting to split "things" across multiple processes.

=== Example 1: Hello World (from the Model)

link:./src/main/java/ch/petikoch/examples/mvvm_rxjava/example1[]

* The Model pushes "hello world's" thru an Observable to the ViewModel (using a computational thread)
* A JLabel in the View is bound to the `vm2v_info` field of the ViewModel
* The `RxViewModel2SwingViewBinder` code does the switch to the `SwingScheduler`
{'fraction_non_alphanumeric': 0.090815697554962, 'fraction_numerical': 0.00465721525922882, 'mean_word_length': 4.876056338028169, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 22, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7335875', 'n_tokens_mistral': 4314, 'n_tokens_neox': 4063, 'n_words': 1825}