/* * Copyright (c) 2013-2017 Chris Newland. * Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD * Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki */ package org.adoptopenjdk.jitwatch.ui.stage; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.adoptopenjdk.jitwatch.ui.report.ReportStage; import org.adoptopenjdk.jitwatch.util.UserInterfaceUtil; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.stage.WindowEvent; public class StageManager { private static Map<Stage, List<Stage>> openStages = new HashMap<>(); private static List<IStageClosedListener> listeners = new ArrayList<>(); private StageManager() { } public static void registerListener(IStageClosedListener listener) { listeners.add(listener); } private static void notifyListeners(Stage stage) { for (IStageClosedListener listener : listeners) { listener.handleStageClosed(stage); } } public static void clearReportStages() { for (Stage rootStage : openStages.keySet()) { clearChildren(rootStage); } } public static void clearChildren(Stage stage) { if (openStages.containsKey(stage)) { for (Stage childStage : openStages.get(stage)) { clearChildren(childStage); } } if (stage instanceof ReportStage) { ((ReportStage) stage).clear(); } } // Adds a close buttong to stages // for fullscreen JavaFX systems with no window decorations private static void addCloseButton(final Stage stage) { Scene scene = stage.getScene(); Parent rootNode = scene.getRoot(); Button btnClose = new Button("X"); btnClose.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { closeStage(stage); } }); HBox hbox = new HBox(); hbox.setSpacing(16); hbox.getChildren().addAll(btnClose, new Label(stage.getTitle())); if (rootNode instanceof BorderPane) { BorderPane pane = (BorderPane) rootNode; Node topNode = pane.getTop(); if (topNode instanceof VBox) { VBox vbox = (VBox) topNode; vbox.getChildren().add(0, hbox); } else { VBox newTopNode = new VBox(); newTopNode.setPadding(new Insets(0)); newTopNode.getChildren().addAll(hbox, topNode); pane.setTop(newTopNode); } } else { VBox newTopNode = new VBox(); newTopNode.setPadding(new Insets(0)); newTopNode.getChildren().addAll(hbox, rootNode); scene.setRoot(newTopNode); } } public static void addAndShow(final Stage parent, final Stage childStage) { addAndShow(parent, childStage, null); } public static void addAndShow(final Stage parent, final Stage childStage, final IStageClosedListener closedListener) { List<Stage> childrenOfParent = openStages.get(parent); if (childrenOfParent == null) { childrenOfParent = new ArrayList<>(); openStages.put(parent, childrenOfParent); } childrenOfParent.add(childStage); if (UserInterfaceUtil.ADD_CLOSE_DECORATION) { addCloseButton(childStage); } childStage.setOnCloseRequest(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent arg0) { if (closedListener != null) { closedListener.handleStageClosed(childStage); } closeStage(childStage); } }); childStage.show(); double parentX = parent.getX(); double parentY = parent.getY(); double parentWidth = parent.getWidth(); double parentHeight = parent.getHeight(); double childWidth = childStage.getWidth(); double childHeight = childStage.getHeight(); double childX = parentX + (parentWidth - childWidth) / 2; double childY = parentY + (parentHeight - childHeight) / 2; childStage.setX(childX); childStage.setY(childY); } public static EventHandler<ActionEvent> getCloseHandler(final Stage stage) { return new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { StageManager.closeStage(stage); } }; } public static void closeStage(Stage stage) { List<Stage> childrenOfParent = openStages.get(stage); if (childrenOfParent != null) { for (Stage child : childrenOfParent) { closeStage(child); } } notifyListeners(stage); openStages.remove(stage); stage.close(); } }