diff --git a/README.md b/README.md
index ad53de0..83f5dc5 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ for that purpose, I've created javafx-scene-router. It allows you to initialize
a router that controls the content of a Pane or similar, and depending on what
route is selected, different content will be shown in that pane.
-# Usage
+## Usage
Add the following dependency to your `pom.xml`:
```xml
@@ -83,3 +83,22 @@ public class MainController {
}
}
```
+
+## Reactivity
+
+The SceneRouter has been designed to be used in reactive JavaFX projects, and
+includes a few ways of doing this:
+
+- The `currentRouteProperty` can be bound to, or have a listener attached, to
+update each time the current route changes.
+- You can `getBreadCrumbs()` to get an observable list of breadcrumbs that
+changes each time the route's history changes.
+- You can use `addRouteChangeListener` to add a listener that's notified each
+time the route has changed, with additional context and the previous route.
+- You can use `addRouteSelectionListener` to add a listener for a specific
+route, that will be notified only when the router selects that route.
+- You can make any of your controllers for route nodes implement `RouteSelectionListener`,
+in which case they'll automatically be registered using `addRouteSelectionListener`.
+Note that this **does not** apply to routes mapped using a pre-loaded node, as
+in the `map(String route, Parent node)` method. Only methods which take a `URL`
+to a resource work with this.
diff --git a/pom.xml b/pom.xml
index b1d4388..c2b16d9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
+ * Note that by supplying a pre-loaded JavaFX node, the SceneRouter is + * no longer able to check if the node's controller implements + * {@link RouteSelectionListener}, and so you'll need to register the + * controller manually with {@link #addRouteSelectionListener(String, RouteSelectionListener)} + * in order to have the controller be notified when its contents are + * shown. + *
* @param route The route. * @param node The node to show. * @return This router. @@ -66,7 +82,7 @@ public class SceneRouter { * @return This router. */ public SceneRouter map(String route, URL fxml, Consumer> controllerCustomizer) { - return map(route, loadNode(fxml, controllerCustomizer)); + return map(route, loadNode(route, fxml, controllerCustomizer)); } /** @@ -85,9 +101,11 @@ public class SceneRouter { * @param context The context that should be available at that route. */ public void navigate(String route, Object context) { + String oldRoute = currentRouteProperty.get(); + Object oldContext = history.getCurrentContext(); Platform.runLater(() -> { history.push(route, context); - setCurrentNode(getMappedNode(route)); + setCurrentNode(route, oldRoute, oldContext); }); } @@ -103,18 +121,18 @@ public class SceneRouter { * Attempts to navigate back. */ public void navigateBack() { - Platform.runLater(() -> history.back() - .ifPresent(prev -> setCurrentNode(getMappedNode(prev.route()))) - ); + String oldRoute = currentRouteProperty.get(); + Object oldContext = history.getCurrentContext(); + Platform.runLater(() -> history.back().ifPresent(prev -> setCurrentNode(prev.route(), oldRoute, oldContext))); } /** * Attempts to navigate forward. */ public void navigateForward() { - Platform.runLater(() -> history.forward() - .ifPresent(next -> setCurrentNode(getMappedNode(next.route()))) - ); + String oldRoute = currentRouteProperty.get(); + Object oldContext = history.getCurrentContext(); + Platform.runLater(() -> history.forward().ifPresent(next -> setCurrentNode(next.route(), oldRoute, oldContext))); } /** @@ -143,6 +161,14 @@ public class SceneRouter { return viewPane; } + /** + * Gets a property that refers to the router's current route. + * @return The route property. + */ + public StringProperty currentRouteProperty() { + return currentRouteProperty; + } + /** * Gets an observable list of {@link BreadCrumb} that is updated each time * the router's navigation history is updated. @@ -152,6 +178,25 @@ public class SceneRouter { return breadCrumbs; } + /** + * Adds a listener that will be notified each time the current route changes. + * @param listener The listener that will be notified. + */ + public void addRouteChangeListener(RouteChangeListener listener) { + routeChangeListeners.add(listener); + } + + /** + * Adds a listener that will be notified when the route changes to a + * specified route. + * @param route The route to listen for. + * @param listener The listener to use. + */ + public void addRouteSelectionListener(String route, RouteSelectionListener listener) { + List