diff --git a/pom.xml b/pom.xml
index c738535..3149ddb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.andrewlalis
javafx-scene-router
- 1.5.1
+ 1.6.0
JavaFX Scene Router
A library that provides a router implementation for JavaFX, for browser-like navigation between pages.
https://github.com/andrewlalis/javafx-scene-router
diff --git a/src/main/java/com/andrewlalis/javafx_scene_router/AnchorPaneRouterView.java b/src/main/java/com/andrewlalis/javafx_scene_router/AnchorPaneRouterView.java
index cbff6d1..b2cbe04 100644
--- a/src/main/java/com/andrewlalis/javafx_scene_router/AnchorPaneRouterView.java
+++ b/src/main/java/com/andrewlalis/javafx_scene_router/AnchorPaneRouterView.java
@@ -7,8 +7,7 @@ import javafx.scene.layout.AnchorPane;
* A router view implementation using the JavaFX {@link AnchorPane}, so that
* route contents can (optionally) be grown to fill all available space.
*/
-public class AnchorPaneRouterView implements RouterView {
- private final AnchorPane anchorPane = new AnchorPane();
+public class AnchorPaneRouterView extends SimpleRouterView {
private final boolean expandContents;
/**
@@ -18,6 +17,7 @@ public class AnchorPaneRouterView implements RouterView {
* fill all available space.
*/
public AnchorPaneRouterView(boolean expandContents) {
+ super(new AnchorPane());
this.expandContents = expandContents;
}
@@ -43,14 +43,6 @@ public class AnchorPaneRouterView implements RouterView {
AnchorPane.setBottomAnchor(node, 0.0);
AnchorPane.setLeftAnchor(node, 0.0);
}
- anchorPane.getChildren().setAll(node);
- }
-
- /**
- * Gets the underlying pane used for rendering.
- * @return The anchor pane this view uses.
- */
- public AnchorPane getAnchorPane() {
- return anchorPane;
+ super.showRouteNode(node);
}
}
diff --git a/src/main/java/com/andrewlalis/javafx_scene_router/SceneRouter.java b/src/main/java/com/andrewlalis/javafx_scene_router/SceneRouter.java
index 79a54c1..b35cf3d 100644
--- a/src/main/java/com/andrewlalis/javafx_scene_router/SceneRouter.java
+++ b/src/main/java/com/andrewlalis/javafx_scene_router/SceneRouter.java
@@ -102,6 +102,23 @@ public class SceneRouter {
return map(route, fxml, null);
}
+ /**
+ * "Warms up" the route cache by calling each route's supplier once. This
+ * will cause FXML resources to be loaded, such that all subsequent loads
+ * are much faster.
+ * @return A future that's complete once all routes are loaded.
+ */
+ public CompletableFuture loadAllRoutes() {
+ CompletableFuture cf = new CompletableFuture<>();
+ Thread.ofVirtual().start(() -> {
+ for (Supplier nodeSupplier : routeMap.values()) {
+ nodeSupplier.get();
+ }
+ cf.complete(null);
+ });
+ return cf;
+ }
+
/**
* Navigates to a given route, with a given context object.
* @param route The route to navigate to.
@@ -188,6 +205,34 @@ public class SceneRouter {
return cf;
}
+ /**
+ * Navigates to the given route, clearing any previous history.
+ * @param route The route to navigate to.
+ * @param context The context for the route.
+ * @return A future that resolves once navigation is complete.
+ */
+ public CompletableFuture replace(String route, Object context) {
+ String oldRoute = currentRouteProperty.get();
+ Object oldContext = history.getCurrentContext();
+ CompletableFuture cf = new CompletableFuture<>();
+ Platform.runLater(() -> {
+ history.clear();
+ history.push(route, context);
+ setCurrentNode(route, oldRoute, oldContext);
+ cf.complete(null);
+ });
+ return cf;
+ }
+
+ /**
+ * Navigates to the given route, clearing any previous history.
+ * @param route The route to navigate to.
+ * @return A future that resolves once navigation is complete.
+ */
+ public CompletableFuture replace(String route) {
+ return replace(route, null);
+ }
+
/**
* Gets the context object for the current route.
* @return The context object, or null.
@@ -282,6 +327,9 @@ public class SceneRouter {
if (controller instanceof RouteSelectionListener rsl) {
addRouteSelectionListener(route, rsl);
}
+ if (controller instanceof RouteChangeListener rcl) {
+ addRouteChangeListener(rcl);
+ }
if (controllerCustomizer != null) {
if (controller == null) throw new IllegalStateException("No controller found when loading " + resource.toString());
controllerCustomizer.accept(controller);
diff --git a/src/main/java/com/andrewlalis/javafx_scene_router/SimplePaneRouterView.java b/src/main/java/com/andrewlalis/javafx_scene_router/SimplePaneRouterView.java
deleted file mode 100644
index 124c8f3..0000000
--- a/src/main/java/com/andrewlalis/javafx_scene_router/SimplePaneRouterView.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.andrewlalis.javafx_scene_router;
-
-import javafx.scene.Parent;
-import javafx.scene.layout.Pane;
-
-/**
- * A simple router view implementation that uses a JavaFX Pane, which shows
- * the route contents in their preferred minimal size.
- */
-public class SimplePaneRouterView implements RouterView {
- private final Pane pane = new Pane();
-
- /**
- * Shows the node in the pane.
- * @param node The node to show.
- */
- @Override
- public void showRouteNode(Parent node) {
- pane.getChildren().setAll(node);
- }
-
- /**
- * Gets the pane that's used internally to show the contents.
- * @return The pane.
- */
- public Pane getPane() {
- return pane;
- }
-}
diff --git a/src/main/java/com/andrewlalis/javafx_scene_router/SimpleRouterView.java b/src/main/java/com/andrewlalis/javafx_scene_router/SimpleRouterView.java
new file mode 100644
index 0000000..8dbe0f0
--- /dev/null
+++ b/src/main/java/com/andrewlalis/javafx_scene_router/SimpleRouterView.java
@@ -0,0 +1,39 @@
+package com.andrewlalis.javafx_scene_router;
+
+import javafx.scene.Parent;
+import javafx.scene.layout.Pane;
+
+/**
+ * A simple implementation of {@link RouterView} which simply keeps a reference
+ * to a {@link Pane} and displays any route nodes inside that pane by setting
+ * its only child to the given route node.
+ * @param The pane type.
+ */
+public class SimpleRouterView implements RouterView {
+ /**
+ * The pane in which route nodes are displayed.
+ */
+ private final T pane;
+
+ /**
+ * Constructs this router view to use the given pane.
+ * @param pane The pane to use.
+ */
+ public SimpleRouterView(T pane) {
+ this.pane = pane;
+ }
+
+ @Override
+ public void showRouteNode(Parent node) {
+ this.pane.getChildren().clear();
+ this.pane.getChildren().add(node);
+ }
+
+ /**
+ * Gets the pane used by this router view.
+ * @return The pane used by this router view.
+ */
+ public T getPane() {
+ return this.pane;
+ }
+}
diff --git a/src/main/java/com/andrewlalis/javafx_scene_router/component/RouterLink.java b/src/main/java/com/andrewlalis/javafx_scene_router/component/RouterLink.java
new file mode 100644
index 0000000..6f9bdfc
--- /dev/null
+++ b/src/main/java/com/andrewlalis/javafx_scene_router/component/RouterLink.java
@@ -0,0 +1,60 @@
+package com.andrewlalis.javafx_scene_router.component;
+
+import com.andrewlalis.javafx_scene_router.SceneRouter;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.fxml.FXML;
+import javafx.scene.control.Hyperlink;
+
+/**
+ * A hyperlink that, when clicked, navigates the user to a specified route.
+ */
+public class RouterLink extends Hyperlink {
+ @FXML
+ private final StringProperty routeProperty = new SimpleStringProperty(this, "route", null);
+ @FXML
+ private final ObjectProperty routerProperty = new SimpleObjectProperty<>(this, "router", null);
+
+ private Object context;
+
+ // Route property.
+ public StringProperty routeProperty() {
+ return routeProperty;
+ }
+
+ public final void setRoute(String route) {
+ this.context = null;
+ routeProperty.set(route);
+ setOnAction(event -> {
+ SceneRouter router = getRouter();
+ String currentRoute = getRoute();
+ if (router != null && currentRoute != null) {
+ router.navigate(currentRoute, context);
+ }
+ });
+ }
+
+ public final void setRoute(String route, Object context) {
+ this.context = context;
+ setRoute(route);
+ }
+
+ public final String getRoute() {
+ return routeProperty.get();
+ }
+
+ // Router property.
+ public ObjectProperty routerProperty() {
+ return routerProperty;
+ }
+
+ public final void setRouter(SceneRouter router) {
+ routerProperty.set(router);
+ }
+
+ public final SceneRouter getRouter() {
+ return routerProperty.get();
+ }
+}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 12979d8..53be422 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -4,6 +4,9 @@
module com.andrewlalis.javafx_scene_router {
requires javafx.fxml;
requires javafx.graphics;
+ requires javafx.controls;
exports com.andrewlalis.javafx_scene_router;
+ exports com.andrewlalis.javafx_scene_router.component;
+ opens com.andrewlalis.javafx_scene_router.component to javafx.fxml;
}