All Projects → Petikoch → Java_MVVM_with_Swing_and_RxJava_Examples

Petikoch / Java_MVVM_with_Swing_and_RxJava_Examples

Licence: Apache-2.0 license
Explorative Java Swing GUI example code from 2016 with an implementation of MVVM (Model View ViewModel) using RxJava and RxSwing. DON'T use it in production, there are some open issues here!

Programming Languages

java
68154 projects - #9 most used programming language
groovy
2714 projects

Projects that are alternatives of or similar to Java MVVM with Swing and RxJava Examples

Reactivenetwork
Android library listening network connection state and Internet connectivity with RxJava Observables
Stars: ✭ 2,484 (+2487.5%)
Mutual labels:  rxjava
Coderfun
knowledge&girls,RxJava&Retrofit&DBFlow
Stars: ✭ 233 (+142.71%)
Mutual labels:  rxjava
jExifToolGUI
jExifToolGUI is a multi-platform java/Swing graphical frontend for the excellent command-line ExifTool application by Phil Harvey
Stars: ✭ 267 (+178.13%)
Mutual labels:  swing-gui
Countdownlist
CountDown 倒计时的各种花式实现
Stars: ✭ 222 (+131.25%)
Mutual labels:  rxjava
Prefser
Wrapper for Android SharedPreferences with object serialization and RxJava Observables
Stars: ✭ 228 (+137.5%)
Mutual labels:  rxjava
Storio
Reactive API for SQLiteDatabase and ContentResolver.
Stars: ✭ 2,594 (+2602.08%)
Mutual labels:  rxjava
Neteasecloudmusic
仿网易云音乐安卓客户端V6.0
Stars: ✭ 213 (+121.88%)
Mutual labels:  rxjava
RxUploader
Uploader for Android using RxJava
Stars: ✭ 72 (-25%)
Mutual labels:  rxjava
Movieguide
Movie discovery app showcasing MVP, RxJava, Dagger 2 and Clean Architecture
Stars: ✭ 2,573 (+2580.21%)
Mutual labels:  rxjava
Kpermissions
A Kotlin library which helps to request runtime permissions in Android.
Stars: ✭ 253 (+163.54%)
Mutual labels:  rxjava
Bubbble
Sample app showcases the MVP pattern and Robert Martin's Clean Architecture approach.
Stars: ✭ 226 (+135.42%)
Mutual labels:  rxjava
Rxjavareactivestreams
Adapter between RxJava and ReactiveStreams
Stars: ✭ 227 (+136.46%)
Mutual labels:  rxjava
Reactive Billing
Lightweight reactive wrapper around In App Billing API v3 for Android
Stars: ✭ 251 (+161.46%)
Mutual labels:  rxjava
Movieguide Kotlin
Movie discovery app showcasing Kotlin, RxJava, Dagger2, MVP using Clean Architecture
Stars: ✭ 222 (+131.25%)
Mutual labels:  rxjava
openhospital-gui
Open Hospital GUI (Java Swing) component
Stars: ✭ 27 (-71.87%)
Mutual labels:  swing-gui
Rxfit
🏃Reactive Fitness API Library for Android and RxJava
Stars: ✭ 218 (+127.08%)
Mutual labels:  rxjava
Android Mvvm Architecture
This repository contains a detailed sample app that implements MVVM architecture using Dagger2, Room, RxJava2, FastAndroidNetworking and PlaceholderView
Stars: ✭ 2,720 (+2733.33%)
Mutual labels:  rxjava
photon
Fast and light image loading library based on kotlin
Stars: ✭ 20 (-79.17%)
Mutual labels:  rxjava
willsautoclick
Fastest Java autoclicker in the entire west
Stars: ✭ 12 (-87.5%)
Mutual labels:  swing-gui
Relax
☘☘Relax 基于Kotlin语言编写的一套组件化框架,不紧整体组件化、内部也高度组件化🎋你可配置MVP、MVVM的开发模式、也可以配置所需要的业务组件🍁🍁
Stars: ✭ 253 (+163.54%)
Mutual labels:  rxjava

Java MVVM with Swing, RxJava and RxSwing examples

Apache License 2 Build Status

Introduction

There are a lot of different architectures for the GUI: Model View Controller, Model View Presenter, Model View ViewModel, 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 MVVM and came up with the idea of

  • using RxJava's Subject objects as "listenable" value objects for the ViewModel

  • RxSwing to connect the View widgets (JButton, JTextField, …​) to the ViewModel-Subjects as "data binding"

  • 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 Scheduler and the RxSwing SwingScheduler to do the threading

Java MVVM RxJava basic idea

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:

MVVMPattern
  • 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:

MVVM dependencies
  • 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

    • 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 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)

  • 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

example1

Tests:

Example 2: Form submit

  • A simple form submit of two textfields

  • The ViewModel combines the two textfield values into one DTO and calls the Model API on a IO-Thread

  • The RxModelInvoker code does the switch to the Schedulers.io() scheduler

example2

This example is the implementation of the initial idea:

Java MVVM RxJava basic idea

Screencast with live coding:
https://www.youtube.com/watch?v=wjZ6xJkWD-U

example2 introduction screencast

Tests:

Example 3: Form submit with Submit Button enabling

  • Same as Example 2

  • But: Submit button is only enabled, if both textfields contain a value

Tests:

Example 4: Form submit with form disabling / reenabling

  • Same as Example 3

  • But: The form is completely disabled during the submit processing time

Tests:

Example 5: Form submit with cancellation and classic "blocking" Model API

  • Same as Example 4

  • You can cancel the submit processing

  • The Model has a classic "blocking" API

example5

Tests:

Example 5a: Form submit with cancellation and "non-blocking" Model API

  • Same as Example 5

  • The Model has a "non-blocking" API, the ViewModel gets simpler

Tests:

Example 6: Form submit with combining two asynchronous backend actions

  • Same as Example 5a

  • But with two Model API calls running in two different threads

  • Waiting for both of them

  • Cancellation for both of them

example6

Tests:

Example 6a: Form submit with exceptions in Model (backend) calls

  • Same as Example 6

  • But like in real world, there are sometimes exceptions during e.g. Model (backend) method calls

  • How to handle them?

This is of course a challenging task:
How to combine results from asynchronous tasks in general?
How to handle exceptions in those?

This is a typical problem which solves RxJava easily: It offers all the necessary API’s.
See e.g. https://github.com/ReactiveX/RxJava/wiki/Error-Handling-Operators or of course the onError in rx.Observable#subscribe(..).

example6a

Tests:

Example 7: Log table with LogRow’s pushed up from the Model

  • The Model publishes LogRow s (using a computational thread)

  • These are added in the View as rows of a JTable (using GUI thread)

example7

Tests:

Example 7a: Log table with LogRow’s pushed up from the Model and exception handling

  • Same as example 7

  • But: The Model’s log Observable sometimes fail

  • We add some exception handling into the ViewModel, to keep the View alive

example7a

Tests:

Example 8: Log table with LogRow’s pushed up from the Model and dealing with backpressure

  • The Model uses a threadpool to create plenty of LogRow s (using as many threads as there are CPU cores)

  • Since the View runs on a single thread, it can’t keep up with the pace

    • "Fast producer, slow consumer" kind of problem

  • We need to think about backpressure

    • We could slow down the LogRow production (blocking backpressure)

    • Or we could drop the LogRow s which are "too much", keep up "full speed" and show only some of the LogRow s

    • The example uses dropping

example8

Tests:

Example 9: Structural changes at runtime in the View (and GUI composition)

  • So far the views were very static

  • Now we have structural changes at runtime, think of a wizard with it’s steps

  • Parts of the views remain static (header, footer)

  • Therefore we need some kind of View composition

example9
example9 2

Tests:

Example 10: Composition of GUI’s and communication from outer ViewModel’s to inner ViewModel’s

  • View / ViewModel composition

    • How can on "outer" component communicate with "inner" components?

      • How to propagate the "edit" state to the inner components?

example10

Tests:

Example 11: Composition of GUI’s and communication from inner ViewModel’s to outer ViewModel’s (dirty flag, Save Button)

  • View / ViewModel composition

    • How can on "inner" component communicate with an "outer" component?

      • "Dirty" flag of "inner" component enables the "Save" button of "outer" component

example11

Tests:

Requirements

  • Java 8 or later

Feedback

Please use GitHub issues and pull requests for feedback or contributions.

What’s next?

These examples do only answer some of the inital questions. It’s work in progress. Feel free to get in touch with me, give feedback, contribute some more examples…​ :-)

Best regards,

Signature
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].