Updated to use router view strategy instead.

This commit is contained in:
Andrew Lalis 2023-12-25 18:12:24 -05:00
parent 18ab61be28
commit 48e150c3c3
7 changed files with 145 additions and 20 deletions

View File

@ -46,20 +46,23 @@ public class MyJavaFXApp extends Application {
} }
``` ```
From here, it's just a matter of attaching the router's view pane to one of From here, it's just a matter of attaching the router's view to one of
your scene's nodes, and mapping string route names to other nodes or FXML your scene's nodes, and mapping string route names to other nodes or FXML
files. files.
For example, suppose my app has a main scene with a `MainController` class. For example, suppose my app has a main scene with a `MainController` class.
We'd hook up the router's view pane to that scene's center view: We'd hook up the router's view to that scene's center view, assuming you're
using an AnchorPaneRouterView for your router (the default choice).
```java ```java
public class MainController { public class MainController {
@FXML @FXML
public BorderPane borderPane; public BorderPane borderPane;
@FXML @FXML
public void initialize() { public void initialize() {
borderPane.setCenter(MyJavaFXApp.router.getViewPane()); AnchorPaneRouterView view = (AnchorPaneRouterView) MyJavaFXApp.router.getView();
borderPane.setCenter(view.getAnchorPane());
} }
} }
``` ```

View File

@ -6,7 +6,7 @@
<groupId>com.andrewlalis</groupId> <groupId>com.andrewlalis</groupId>
<artifactId>javafx-scene-router</artifactId> <artifactId>javafx-scene-router</artifactId>
<version>1.3.0</version> <version>1.4.0</version>
<name>JavaFX Scene Router</name> <name>JavaFX Scene Router</name>
<description>A library that provides a router implementation for JavaFX, for browser-like navigation between pages.</description> <description>A library that provides a router implementation for JavaFX, for browser-like navigation between pages.</description>
<url>https://github.com/andrewlalis/javafx-scene-router</url> <url>https://github.com/andrewlalis/javafx-scene-router</url>

View File

@ -0,0 +1,56 @@
package com.andrewlalis.javafx_scene_router;
import javafx.scene.Parent;
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();
private final boolean expandContents;
/**
* Constructs this router view with an explicit setting for whether to
* expand contents of the view.
* @param expandContents Whether to expand the contents of this view to
* fill all available space.
*/
public AnchorPaneRouterView(boolean expandContents) {
this.expandContents = expandContents;
}
/**
* Constructs this router view with the default behavior of allowing route
* contents to fill all available space.
*/
public AnchorPaneRouterView() {
this(true);
}
/**
* Shows the node in this view's anchor pane. If this view has been set to
* expand contents, then the given node will be anchored to all 4 sides of
* the anchor pane.
* @param node The node to show.
*/
@Override
public void showRouteNode(Parent node) {
if (expandContents) {
AnchorPane.setTopAnchor(node, 0.0);
AnchorPane.setRightAnchor(node, 0.0);
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;
}
}

View File

@ -0,0 +1,15 @@
package com.andrewlalis.javafx_scene_router;
/**
* A listener that's invoked when a router's route is updated.
*/
public interface RouteChangeListener {
/**
* Called when a router's route changes.
* @param route The route that was navigated to.
* @param context The context at the new route.
* @param oldRoute The previous route.
* @param oldContext The context at the previous route.
*/
void routeChanged(String route, Object context, String oldRoute, Object oldContext);
}

View File

@ -0,0 +1,18 @@
package com.andrewlalis.javafx_scene_router;
import javafx.scene.Parent;
/**
* An interface through which a router can show a route's node in the application.
* <p>
* Usually, this will be implemented by adding the node to some sort of
* container, like a Pane or Stage.
* </p>
*/
public interface RouterView {
/**
* Shows the node as the current one, discarding any previous route content.
* @param node The node to show.
*/
void showRouteNode(Parent node);
}

View File

@ -7,7 +7,6 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.layout.Pane;
import java.io.IOException; import java.io.IOException;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
@ -21,7 +20,7 @@ import java.util.function.Consumer;
* <p> * <p>
* The router has a mapping of "routes" (think, Strings) to JavaFX Parent * The router has a mapping of "routes" (think, Strings) to JavaFX Parent
* nodes. When a route is selected, the router will lookup the mapped node, * nodes. When a route is selected, the router will lookup the mapped node,
* and put that node into the pre-defined pane or consumer function. * and put that node into its configured {@link RouterView} implementation.
* </p> * </p>
* <p> * <p>
* The router maintains a {@link RouteHistory} so that it's possible to * The router maintains a {@link RouteHistory} so that it's possible to
@ -34,11 +33,7 @@ import java.util.function.Consumer;
* </p> * </p>
*/ */
public class SceneRouter { public class SceneRouter {
public interface RouteChangeListener { private final RouterView view;
void routeChanged(String route, Object context, String oldRoute, Object oldContext);
}
private final Pane viewPane = new Pane();
private final Map<String, Parent> routeMap = new HashMap<>(); private final Map<String, Parent> routeMap = new HashMap<>();
private final RouteHistory history = new RouteHistory(); private final RouteHistory history = new RouteHistory();
private final ObservableList<BreadCrumb> breadCrumbs = FXCollections.observableArrayList(); private final ObservableList<BreadCrumb> breadCrumbs = FXCollections.observableArrayList();
@ -48,9 +43,19 @@ public class SceneRouter {
private final Map<String, List<RouteSelectionListener>> routeSelectionListeners = new HashMap<>(); private final Map<String, List<RouteSelectionListener>> routeSelectionListeners = new HashMap<>();
/** /**
* Constructs the router. * Constructs the router with a given router view.
* @param view The view that will display the router's current route contents.
*/ */
public SceneRouter() {} public SceneRouter(RouterView view) {
this.view = view;
}
/**
* Constructs the router with a default {@link AnchorPaneRouterView}.
*/
public SceneRouter() {
this(new AnchorPaneRouterView(true));
}
/** /**
* Maps the given route to a node, so that when the route is selected, the * Maps the given route to a node, so that when the route is selected, the
@ -153,12 +158,11 @@ public class SceneRouter {
} }
/** /**
* Gets the view pane that this router renders to. Take this and put it * Gets the view used by this router.
* somewhere in your view's hierarchy to show the router's content. * @return The router's view.
* @return The router's view pane.
*/ */
public Pane getViewPane() { public RouterView getView() {
return viewPane; return view;
} }
/** /**
@ -211,7 +215,7 @@ public class SceneRouter {
* @param oldContext The context of the previous route. * @param oldContext The context of the previous route.
*/ */
private void setCurrentNode(String route, String oldRoute, Object oldContext) { private void setCurrentNode(String route, String oldRoute, Object oldContext) {
viewPane.getChildren().setAll(getMappedNode(route)); view.showRouteNode(getMappedNode(route));
breadCrumbs.setAll(history.getBreadCrumbs()); breadCrumbs.setAll(history.getBreadCrumbs());
currentRouteProperty.set(route); currentRouteProperty.set(route);
for (var listener : routeChangeListeners) { for (var listener : routeChangeListeners) {

View File

@ -0,0 +1,29 @@
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;
}
}