Skip to content

Commit

Permalink
Cleanup and provide javadoc documentation for the Popup API
Browse files Browse the repository at this point in the history
  • Loading branch information
besidev committed Jul 3, 2024
1 parent 4ea9985 commit 6617aef
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,35 @@
import javafx.scene.layout.StackPane;
import simplefx.experimental.parts.FXFuture;

import java.util.Objects;

/**
* The popupContext is usually a StackPane. Typically, the "RouteNode" of the Routing API, which is a StackPane.
* Provides utility methods for managing popups in a JPro application.
* This includes opening and closing popups, as well as showing a loading screen.
*
* @author Florian Kirmaier
*/
public class PopupAPI {

static Object POPUP_CONTEXT = new Object();
public static final Object POPUP_CONTEXT = new Object();

/**
* Closes a popup with the given content.
* Opens a popup within the specified context.
*
* @param popupContext the pane that will serve as the context for the popup
* @param popup the node representing the popup to be displayed
* @throws RuntimeException if {@code popupContext} is null
*/
public static void openPopup(Pane popupContext, Node popup) {
Objects.requireNonNull(popupContext, "popupContext must not be null");
popup.getProperties().put(POPUP_CONTEXT, popupContext);
popupContext.getChildren().add(popup);
}

/**
* Closes the specified popup node.
*
* @param popupNode the popup node to be closed
*/
public static void closePopup(Node popupNode) {
Node popup = getPopup(popupNode);
Expand All @@ -23,60 +43,49 @@ public static void closePopup(Node popupNode) {
}

/**
* Shows a popup with the given content.
* Shows a loading screen on the specified popup context and binds it to the completion of a future.
*
* @param popupContext the popup context
* @param popup the popup node
* @param <T> the type of the result produced by the future
* @param popupContext the pane that will serve as the context for the loading screen
* @param fxFuture the future whose completion will trigger the removal of the loading screen
* @return the {@link FXFuture} passed as an argument
* @throws RuntimeException if {@code popupContext} is null
*/
public static void openPopup(Pane popupContext, Node popup) {
if (popupContext == null) {
throw new RuntimeException("popupContext must not be null");
}
popup.getProperties().put(POPUP_CONTEXT, popupContext);
popupContext.getChildren().add(popup);
}
public static <T> FXFuture<T> showLoadingScreen(Pane popupContext, FXFuture<T> fxFuture) {
Objects.requireNonNull(popupContext, "popupContext must not be null");

/**
* Shows a loading screen, which is a progress indicator, until the given future is completed.
* Feel encouraged to copy this implementation, and modify it to your needs.
*/
public static <T> FXFuture<T> showLoadingScreen(Pane popupContext, FXFuture<T> fu) {
if (popupContext == null) {
throw new RuntimeException("popupContext must not be null");
}
ProgressIndicator indicator = new ProgressIndicator();
indicator.setMaxWidth(100);
indicator.setMaxHeight(100);
StackPane popup = new StackPane(indicator);
popup.setStyle("-fx-background-color: #00000066;");
openPopup(popupContext, popup);
fu.onComplete((v) -> {
fxFuture.onComplete((v) -> {
indicator.setProgress(1.0);
closePopup(popup);
});
return fu;
return fxFuture;
}

/**
* Gets the PopupContext from the node of a popup. The node can be any node of the popup.
* Retrieves the popup context for a given popup node.
*
* @param popup the node for which to find the popup context
* @return the pane that serves as the context for the popup
*/
public static Pane getPopupContext(Node popup) {
Pane context = (Pane) popup.getProperties().get(POPUP_CONTEXT);
if (context == null) {
return getPopupContext(popup.getParent());
} else {
return context;
}

return (context == null) ? getPopupContext(popup.getParent()) : context;
}

/**
* Retrieves the popup node from a given node, if it exists.
*
* @param popupNode the node from which to retrieve the popup
* @return the node representing the popup, or the input node if no popup context is found
*/
public static Node getPopup(Node popupNode) {
Node context = (Node) popupNode.getProperties().get(POPUP_CONTEXT);
if (context == null) {
return getPopup(popupNode.getParent());
} else {
return popupNode;
}
return (context == null) ? getPopup(popupNode.getParent()) : popupNode;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package one.jpro.platform.routing.popup.simplepopup;


import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
Expand All @@ -11,13 +10,26 @@

import java.util.List;

/**
* Represents a simple popup window with customizable content and buttons.
* This class extends {@link StackPane} to provide a flexible layout for displaying popups.
*
* @author Florian Kirmaier
*/
public class SimplePopup extends StackPane {

VBox popupBox = new VBox();

/**
* Constructs a {@code SimplePopup} with specified title, content, buttons and closability.
*
* @param title the title of the popup
* @param content the main content of the popup as a {@link Node}
* @param buttons a list of {@link Button}s to be displayed at the bottom of the popup
* @param closable a boolean indicating if the popup can be closed by the user
*/
public SimplePopup(String title, Node content, List<Button> buttons, boolean closable) {
getStylesheets().add(getCSSFile());
getStyleClass().add("simple-popup-background");
VBox popupBox = new VBox();
getChildren().add(popupBox);

popupBox.setMaxWidth(Region.USE_PREF_SIZE);
Expand All @@ -26,7 +38,6 @@ public SimplePopup(String title, Node content, List<Button> buttons, boolean clo

Node topArea = createTopArea(title, closable);
popupBox.getChildren().add(topArea);

popupBox.getChildren().add(createContentArea(content));

Node buttonArea = createButtonArea(buttons);
Expand All @@ -37,6 +48,13 @@ public String getCSSFile() {
return "/one/jpro/routing/popup/simplepopup/simplepopup.css";
}

/**
* Creates the top area of the popup, including the title and optional close button.
*
* @param title the title of the popup
* @param closable indicates if a close button should be included
* @return a {@link Node} representing the top area of the popup
*/
public Node createTopArea(String title, boolean closable) {
StackPane topArea = new StackPane();
topArea.getStyleClass().add("simple-popup-top-area");
Expand All @@ -45,22 +63,26 @@ public Node createTopArea(String title, boolean closable) {
titleLabel.getStyleClass().add("simple-popup-title");
topArea.getChildren().add(titleLabel);

if(closable) {
if (closable) {
Button closeButton = new Button();
closeButton.getStyleClass().add("simple-popup-close-button");
// Set ikonli close icon
FontIcon closeIcon = new FontIcon("eva-close");
closeButton.setGraphic(closeIcon);
StackPane.setAlignment(closeButton, Pos.CENTER_RIGHT);
closeButton.setOnAction(e -> {
PopupAPI.closePopup(this);
});
closeButton.setOnAction(e -> PopupAPI.closePopup(this));
topArea.getChildren().add(closeButton);
}

return topArea;
}

/**
* Creates the content area of the popup.
*
* @param content the main content of the popup as a {@link Node}
* @return a {@link Node} representing the content area of the popup
*/
public Node createContentArea(Node content) {
StackPane contentArea = new StackPane();
VBox.setVgrow(contentArea, Priority.ALWAYS);
Expand All @@ -69,6 +91,12 @@ public Node createContentArea(Node content) {
return contentArea;
}

/**
* Creates the button area of the popup.
*
* @param buttons a list of {@link Button}s to be displayed at the bottom of the popup
* @return a {@link Node} representing the button area of the popup
*/
public Node createButtonArea(List<Button> buttons) {
HBox buttonArea = new HBox();
buttonArea.getStyleClass().add("simple-popup-button-area");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,50 @@
import javafx.scene.control.Label;
import one.jpro.platform.routing.popup.PopupAPI;

import java.util.Arrays;
import java.util.List;

/**
* This class contains various static methods to create SimplePopup.
* Utility class for creating simple popups in a JPro application.
*
* @author Florian Kirmaier
*/
public class SimplePopups {

/**
* Creates an informational popup with a specified title and text content.
* The popup includes a close button that, when clicked, will close the popup.
*
* @param title the title of the popup
* @param infoText the text content of the popup
* @return a {@link SimplePopup} object configured with the title, text content, and a close button
*/
public static SimplePopup infoPopup(String title, String infoText) {

Button closeButton = createCloseButton();

SimplePopup popup = new SimplePopup(title, createText(infoText), Arrays.asList(closeButton), true);

return popup;
return new SimplePopup(title, createText(infoText), List.of(closeButton), true);
}

/**
* Creates a text node for displaying in the popup.
* The text is styled with a CSS class for consistent appearance.
*
* @param text the text to be displayed
* @return a {@link Node} containing the text, styled appropriately
*/
public static Node createText(String text) {
Label label = new Label(text);
label.getStyleClass().add("simple-popup-text");
return label;
}

/**
* Creates a button for closing the popup.
* The button is configured with an action to close the popup when clicked.
*
* @return a {@code Button} configured to close the popup when clicked
*/
public static Button createCloseButton() {
Button closeButton = new Button("Close");
closeButton.setOnAction(e -> {
PopupAPI.closePopup(closeButton);
});
closeButton.setOnAction(event -> PopupAPI.closePopup(closeButton));
return closeButton;
}
}

0 comments on commit 6617aef

Please sign in to comment.