/* * Copyright [2014] [Christian Loehnert, krampenschiesser@gmail.com] * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.ks.application; import com.google.common.collect.MapMaker; import de.ks.executor.JavaFXExecutorService; import de.ks.util.FXPlatform; import javafx.collections.FXCollections; import javafx.collections.ObservableMap; import javafx.scene.Node; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import javafx.stage.Window; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; import java.util.concurrent.ConcurrentMap; /** * */ public class Navigator { private static final Logger log = LoggerFactory.getLogger(Navigator.class); private static ConcurrentMap<Window, Navigator> navigators = new MapMaker().weakKeys().makeMap(); public static Navigator getCurrentNavigator() { for (Map.Entry<Window, Navigator> entry : navigators.entrySet()) { Window window = entry.getKey(); if (window.isFocused() && window.isShowing()) { return entry.getValue(); } } if (navigators.size() == 1) { return navigators.entrySet().iterator().next().getValue(); } throw new IllegalStateException("Could not resolve the current navigator. Registered: " + navigators.values()); } /** * @param node * @return the navigator associated with the window of this node. */ public static Navigator getNavigator(Node node) { return navigators.get(node.getScene().getWindow()); } public static Navigator getNavigator(Window stage) { return navigators.get(stage); } public static Navigator register(Window stage, Pane root) { Navigator navigator = new Navigator(root); Navigator old = navigators.remove(stage); if (old != null) { log.warn("Replacing root pane of navigator, old={} new={}", old.getMainArea().getContent(), root); } navigators.put(stage, navigator); return navigator; } public static Navigator registerWithBorderPane(Stage stage) { BorderPane borderPane = new BorderPane(); FXPlatform.invokeLater(() -> { stage.getScene().setRoot(borderPane); borderPane.setCenter(new StackPane()); borderPane.setTop(new StackPane()); borderPane.setBottom(new StackPane()); borderPane.setLeft(new StackPane()); borderPane.setRight(new StackPane()); }); return registerWithExistingPane(stage, borderPane); } public static Navigator registerWithExistingPane(Stage stage, BorderPane borderPane) { Navigator navigator = new Navigator((Pane) borderPane.getCenter()); if (borderPane.getTop() instanceof Pane) { navigator.addPresentationArea(TOP_AREA, (Pane) borderPane.getTop()); } if (borderPane.getBottom() instanceof Pane) { navigator.addPresentationArea(BOTTOM_AREA, (Pane) borderPane.getBottom()); } if (borderPane.getLeft() instanceof Pane) { navigator.addPresentationArea(LEFT_AREA, (Pane) borderPane.getLeft()); } if (borderPane.getRight() instanceof Pane) { navigator.addPresentationArea(RIGHT_AREA, (Pane) borderPane.getRight()); } navigators.put(stage, navigator); return navigator; } public static final String MAIN_AREA = "main"; public static final String LEFT_AREA = "left"; public static final String RIGHT_AREA = "right"; public static final String TOP_AREA = "content"; public static final String BOTTOM_AREA = "bottom"; protected final ObservableMap<String, PresentationArea> presentationAreas = FXCollections.observableHashMap(); // protected final Map<String, Deque<Class<?>>> histories = new HashMap<>(); protected final JavaFXExecutorService fxExecutorService = new JavaFXExecutorService(); private Navigator(Pane mainArea) { addPresentationArea(MAIN_AREA, mainArea); } public void addPresentationArea(String id, Pane pane) { PresentationArea presentationArea = new PresentationArea(id, pane); presentationArea.currentNodeProperty().addListener((observable, previous, current) -> { if (previous != null) { // histories.get(presentationArea.getId()).add() } }); presentationAreas.put(id, presentationArea); } public void presentInMain(Node node) { present(MAIN_AREA, node); } public void present(String area, Node node) { fxExecutorService.submit(() -> { presentationAreas.get(area).setCurrentNode(node); }); } public void back(String area) { } public void next(String area) { } public PresentationArea getPresentationArea(String id) { return presentationAreas.get(id); } public PresentationArea getMainArea() { return getPresentationArea(MAIN_AREA); } }