Add additional documentation
This commit is contained in:
parent
4431841d81
commit
b51f9f5792
97
README.md
97
README.md
@ -8,7 +8,14 @@ it doesn't go as far as it could in facilitating functional and reactive
|
||||
programming. This project is an attempt to add additional facilities that
|
||||
further bridge the beautiful Scala with JavaFX.
|
||||
|
||||
This code is offered as is with now guarantees. You are free to use it if you
|
||||
In particular, here are some key features:
|
||||
|
||||
* Monadic and applicative interfaces on top of `Observable` make it easy to
|
||||
build up computations.
|
||||
* Converters that allow you to use a `Future` or Akka `Stream` as an
|
||||
`Observable`.
|
||||
|
||||
This code is offered as is with no guarantees. You are free to use it if you
|
||||
find it useful, but this is not part of any production project and it may have
|
||||
serious bugs. These APIs may also change at any time, and I make no guarantees
|
||||
that the project will be maintained at all. I welcome any bug reports and I
|
||||
@ -19,3 +26,91 @@ will be happy to merge high-quality pull requests if you find a bug.
|
||||
To use ScalaFX, add the following to your SBT build:
|
||||
|
||||
libraryDependencies += "org.gerweck.scala" %% "scalafx-utils" % "0.9.1"
|
||||
|
||||
## Usage ##
|
||||
|
||||
The primary use of this library is to provide a number of implicit conversions
|
||||
and instances, which are all brought into scope with this import:
|
||||
|
||||
import org.gerweck.scalafx.util._
|
||||
|
||||
If you use Scalaz, this makes ScalaFX observables instances of `Functor`,
|
||||
`Applicative` and `Monad`. It also provides some simple extension methods
|
||||
along these lines.
|
||||
|
||||
### Functional Transformations ###
|
||||
|
||||
Note that the output of a functional transformation is always a
|
||||
`ReadOnlyObjectProperty[A]`, even if there exists a more specific result type
|
||||
like `ReadOnlyIntegerProperty` that would work. (The types used by ScalaFX are
|
||||
fairly complicated, and no real harm is done by using an `ObjectProperty` in
|
||||
all cases.)
|
||||
|
||||
#### Map ####
|
||||
|
||||
To facilitate functional programming, the standard `map` function allows you
|
||||
to transform an observable value using a pure function.
|
||||
|
||||
Note that, for performance reasons, these functionally defined observables do
|
||||
not trigger an update if an input or output value is changed to one that is
|
||||
identical as defined by `equals`.
|
||||
|
||||
import scalafx.beans.value._
|
||||
import scalafx.scene.control._
|
||||
import org.gerweck.scalafx.util._
|
||||
|
||||
val textBox = new TextField { /* ... */ }
|
||||
val boxText: ObservableValue[String, String] = textBox.text
|
||||
/* Construct a new observable derived from the underlying one using `map` */
|
||||
val characterCount: ReadOnlyObjectProperty[String] = textBox.text map (_.size)
|
||||
|
||||
#### Multiple Function Inputs ####
|
||||
|
||||
If your function depends on several observable values, you can use the
|
||||
applicative behavior provided by the library. The Scalaz applicative
|
||||
functionality is all available, but there is a more convenient mechanism for
|
||||
the most common use case where you want to operate on a tuple.
|
||||
|
||||
import scalafx.beans.property._
|
||||
import org.gerweck.scalafx.util._
|
||||
|
||||
val startedDownloads = IntegerProperty(0)
|
||||
val finishedDownloads = IntegerProperty(0)
|
||||
val runningDownloads: ReadOnlyObjectProperty[Int] =
|
||||
(startedDownloads, finishedDownloads).observe map {
|
||||
case (st, fi) => st - fi
|
||||
}
|
||||
|
||||
This `observe` extension method is available on tuples of any arity and
|
||||
efficiently processes updates from any of its dependent values.
|
||||
|
||||
#### Monadically Chained Observables ####
|
||||
|
||||
In addition to the behavior of an applicative functor, this library also
|
||||
provides the ability to act like a monadic functor by providing `flatMap` and
|
||||
`flatten`. *Where possible use the applicative syntax defined above rather
|
||||
than a chain of `flatMap` applications: the applicative format performs much
|
||||
better.*
|
||||
|
||||
Here is an example of a model where you might have a dialog box or window.
|
||||
In this window, you could have a list selection where you choose from one of
|
||||
many transformation types. Once you've selected a transformation type, it will
|
||||
display a configuration panel that you can use to control the details of that
|
||||
transformation.
|
||||
|
||||
import scalafx.beans.property._
|
||||
import org.gerweck.scalafx.util._
|
||||
|
||||
/** An object that has a config dialog that produces a function */
|
||||
trait ConfigurableIntFunction {
|
||||
val typeName: String
|
||||
val configPanel: scalafx.scene.layout.Pane
|
||||
val currentFunction: ReadOnlyObjectProperty[Int => Int]
|
||||
}
|
||||
val selectedFunctionType: ObjectProperty[ConfigurableIntFunction] = ???
|
||||
val selectedFunction = selectedFunctionType flatMap (_.currentFunction)
|
||||
val inputInt = IntegerProperty(0)
|
||||
val outputInt =
|
||||
(selectedFunction, inputInt).observe map {
|
||||
case (sf, ii) => sf(ii)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user