Skip to content

Notification Center Guide

leewyatt edited this page May 12, 2024 · 26 revisions

Overview

GemsFX provides a robust and user-friendly notification management system.

Quick links:

Preview Image

Now, we will create this JavaFX program with notifications together step by step.

image

Key Components

These are some descriptions regarding the core of the notification system, helping us grasp the concepts quickly.

If they are difficult to read, you can skip this section; we will further illustrate using simple code.

Component Description
InfoCenterPane InfoCenterPane is the primary container used in GemsFX for displaying notifications. It is designed to host not only regular views but also to integrate a specialized component, the InfoCenterView, for managing notifications.
InfoCenterView This component is responsible for the management of notification groups within the InfoCenterPane. It organizes how notification groups are displayed and interacted with, providing a streamlined interface for notification handling.
NotificationGroup This model class is used to manage a list of notifications for each group. It allows for notifications within the same group to be handled collectively, supporting functionalities such as view factories for custom notification appearances / visualizations and sorting capabilities to control the order of notifications. One example for such a group could be "Mail" or "Messages".
NotificationView This view class represents the visual representation of a notification. It is where the design and layout of a notification are defined, making it crucial for the visual consistency and appeal of notifications.
NotificationAction Actions can be attached to notifications via Notification.getActions(). The UI will create a control (button or menu item) for each action so that the user can trigger the action. This allows for a quick response on incoming notifications, e.g. "open the mail".
Notification At the core of the system, this class acts as the data model for a notification. It defines attributes / properties of a notification such as its title, summary, and the time of occurrence, providing the information needed for display in a NotificationView.

Getting Started

This guide will demonstrate how you can use GemsFX to create a notification center panel with weather and message notifications.

Tips

  • GemsFX Version: 2.16.0
  • Java Version: 17
  • Images: Icons used in this guide are sourced from https://www.iconarchive.com. License: free for non-commercial use.

Step 1: Create an Application

Start by creating a basic JavaFX application structure and initialize the InfoCenterPane.

import com.dlsc.gemsfx.infocenter.InfoCenterPane;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class SimpleNotificationsApp extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        // 1. Create an instance of InfoCenterPane
        InfoCenterPane infoCenterPane = new InfoCenterPane();
        infoCenterPane.setStyle("-fx-background-color: white;");

        // 2. set the content of the InfoCenterPane
        BorderPane content = new BorderPane();
        Button button = new Button("Create notifications!");
        content.setCenter(button);
        infoCenterPane.setContent(content);

        // 3. Wrap the InfoCenterPane in a StackPane.
        StackPane root = new StackPane(infoCenterPane);
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Rendering Issue and Resolution for InfoCenterPane

Known Issue on Windows

There is a known issue with the InfoCenterPane component on Windows systems where ghost images of previously hidden InfoCenterViews may appear occasionally. This problem does not occur on macOS, suggesting it may be a bug specific to the JavaFX implementation on Windows.

Recommended Solution

To resolve this issue, it is advised not to use InfoCenterPane directly as the root of a Scene. Instead, consider wrapping InfoCenterPane in another layout container, such as a StackPane or another suitable container. This setup effectively eliminates the rendering anomaly and ensures better stability across platforms.

InfoCenterPane infoCenterPane = new InfoCenterPane();
StackPane root = new StackPane(infoCenterPane);

Step 2. Incorporating Weather Notifications

Add weather-related data models and image resources.

import com.dlsc.gemsfx.infocenter.InfoCenterPane;
import com.dlsc.gemsfx.infocenter.Notification;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.time.ZonedDateTime;

public class SimpleNotificationsApp extends Application {

    // 1. Image for Weather
    private final Image weatherImage = new Image("https://icons.iconarchive.com/icons/wineass/ios7-redesign/256/Weather-icon.png", true);

    // 2. Weather Data Model
    public record Weather(ZonedDateTime time, String forecast, String tips, String details) {
    }

    // 3. Weather Notification Data Model
    public static class WeatherNotification extends Notification<Weather> {
        public WeatherNotification(Weather weather) {
            super(weather.forecast(), weather.details, weather.time());
            // 3-1. Optional: set user object to store additional data.
            //       If we need to get some data from the notification, we can use this.
            setUserObject(weather);
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        InfoCenterPane infoCenterPane = new InfoCenterPane();
        infoCenterPane.setStyle("-fx-background-color: white;");

        BorderPane content = new BorderPane();
        Button button = new Button("Create notifications!");
        content.setCenter(button);
        infoCenterPane.setContent(content);
        
        StackPane root = new StackPane(infoCenterPane);
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Step 3. Creating and Adding Weather Notification Groups

Define a weather notification group and add it to the InfoCenterView.

import com.dlsc.gemsfx.infocenter.InfoCenterPane;
import com.dlsc.gemsfx.infocenter.Notification;
import com.dlsc.gemsfx.infocenter.NotificationGroup;
import com.dlsc.gemsfx.infocenter.NotificationView;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.time.ZonedDateTime;

public class SimpleNotificationsApp extends Application {

    private final Image weatherImage = new Image("https://icons.iconarchive.com/icons/wineass/ios7-redesign/256/Weather-icon.png", true);

    public record Weather(ZonedDateTime time, String forecast, String tips, String details) {
    }

    public static class WeatherNotification extends Notification<Weather> {
        public WeatherNotification(Weather weather) {
            super(weather.forecast(), weather.details(), weather.time());
            setUserObject(weather);
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        InfoCenterPane infoCenterPane = new InfoCenterPane();
        infoCenterPane.setStyle("-fx-background-color: white;");

        // 1. Create a Weather Notification Group
        NotificationGroup<Weather, WeatherNotification> weatherGroup = new NotificationGroup<>("Weather");

        // 2. Set View Factory for Weather Group. Convert Notification Data model to View
        weatherGroup.setViewFactory(notification -> {
            // 2-1. Create a NotificationView for Weather
            NotificationView<Weather, WeatherNotification> view = new NotificationView<>(notification);

            // 2-2. Optional: set custom graphic for the notification. if not set, default graphic will be used.
            ImageView graphic = new ImageView(weatherImage);
            graphic.setPreserveRatio(true);
            graphic.setFitWidth(48);
            view.setGraphic(graphic);

            // 2-3. Optional: Set content of the notification view. Here, we are displaying weather tips.
            //     You can customize the content as needed.
            Weather weather = notification.getUserObject();
            view.setContent(new Label(weather.tips()));

            return view;
        });

        // 3. Add Weather Group to InfoCenterPane
        infoCenterPane.getInfoCenterView().getGroups().add(weatherGroup);

        BorderPane content = new BorderPane();
        Button button = new Button("Create notifications!");
        content.setCenter(button);
        infoCenterPane.setContent(content);

        StackPane root = new StackPane(infoCenterPane);
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Step 4. Adding Weather Notifications

Create and add weather notifications to the weather group, illustrating how the Notification system dynamically updates.

image
import com.dlsc.gemsfx.infocenter.InfoCenterPane;
import com.dlsc.gemsfx.infocenter.Notification;
import com.dlsc.gemsfx.infocenter.NotificationGroup;
import com.dlsc.gemsfx.infocenter.NotificationView;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.time.ZonedDateTime;
import java.util.Locale;

public class SimpleNotificationsApp extends Application {

    private final Image weatherImage = new Image("https://icons.iconarchive.com/icons/wineass/ios7-redesign/256/Weather-icon.png", true);

    public record Weather(ZonedDateTime time, String forecast, String tips, String details) {
    }

    public static class WeatherNotification extends Notification<Weather> {
        public WeatherNotification(Weather weather) {
            super(weather.forecast(), weather.details(), weather.time());
            setUserObject(weather);
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        InfoCenterPane infoCenterPane = new InfoCenterPane();
        infoCenterPane.setStyle("-fx-background-color: white;");
        NotificationGroup<Weather, WeatherNotification> weatherGroup = new NotificationGroup<>("Weather");
        weatherGroup.setViewFactory(notification -> {
            NotificationView<Weather, WeatherNotification> view = new NotificationView<>(notification);
            ImageView graphic = new ImageView(weatherImage);
            graphic.setPreserveRatio(true);
            graphic.setFitWidth(48);
            view.setGraphic(graphic);
            Weather weather = notification.getUserObject();
            view.setContent(new Label(weather.tips()));
            return view;
        });

        infoCenterPane.getInfoCenterView().getGroups().add(weatherGroup);

        BorderPane content = new BorderPane();
        Button button = new Button("Create notifications!");
        content.setCenter(button);
        infoCenterPane.setContent(content);
        // 1. After clicking the button, create a new London weather notification and add it to the weather group.
        button.setOnAction(evt -> {
            Weather weather = new Weather(
                    ZonedDateTime.now(),
                    "Sunny",
                    "UV levels high today – wear sunscreen!",
                    "London, 15~24°C, light breeze"
            );
            WeatherNotification weatherNotification = new WeatherNotification(weather);
            weatherGroup.getNotifications().add(weatherNotification);
        });

        StackPane root = new StackPane(infoCenterPane);
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();

        // 2. After 1 second, create a new Zurich weather notification and add it to the weather group.
        PauseTransition pt = new PauseTransition(Duration.seconds(1));
        pt.setOnFinished(e -> {
            Weather zurichWeather = new Weather(
                    ZonedDateTime.now(),
                    "Clear skies",
                    "Ideal for outdoor photography.",
                    "Zurich, 15~20°C, light breeze."
            );
            WeatherNotification weatherNotification = new WeatherNotification(zurichWeather);
            weatherGroup.getNotifications().add(weatherNotification);
        });
        pt.play();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Step 5: Add a new message group.

With the experience gained from creating the weather group, we can now "replicate" this approach to add new message groups.

image
import com.dlsc.gemsfx.infocenter.InfoCenterPane;
import com.dlsc.gemsfx.infocenter.Notification;
import com.dlsc.gemsfx.infocenter.NotificationGroup;
import com.dlsc.gemsfx.infocenter.NotificationView;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.time.ZonedDateTime;
import java.util.Locale;

public class SimpleNotificationsApp extends Application {

    private final Image weatherImage = new Image("https://icons.iconarchive.com/icons/wineass/ios7-redesign/256/Weather-icon.png", true);

    public record Weather(ZonedDateTime time, String forecast, String tips, String details) {
    }

    public static class WeatherNotification extends Notification<Weather> {
        public WeatherNotification(Weather weather) {
            super(weather.forecast(), weather.details(), weather.time());
            setUserObject(weather);
        }
    }

    // Image for the message notification
    private final Image messageImage = new Image("https://icons.iconarchive.com/icons/wineass/ios7-redesign/256/Messages-icon.png", true);

    // Message record
    public record Message(String from, String content, ZonedDateTime time) {
    }

    // Message notification
    public static class MessageNotification extends Notification<Message> {
        public MessageNotification(Message message) {
            super(message.from(), message.content(), message.time());
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        InfoCenterPane infoCenterPane = new InfoCenterPane();
        infoCenterPane.setStyle("-fx-background-color: white;");
        NotificationGroup<Weather, WeatherNotification> weatherGroup = new NotificationGroup<>("Weather");
        weatherGroup.setViewFactory(notification -> {
            NotificationView<Weather, WeatherNotification> view = new NotificationView<>(notification);
            ImageView graphic = new ImageView(weatherImage);
            graphic.setPreserveRatio(true);
            graphic.setFitWidth(48);
            view.setGraphic(graphic);
            Weather weather = notification.getUserObject();
            view.setContent(new Label(weather.tips()));
            return view;
        });

        infoCenterPane.getInfoCenterView().getGroups().add(weatherGroup);

        // Add a message group
        NotificationGroup<Message, MessageNotification> messageGroup = new NotificationGroup<>("Message");
        messageGroup.setViewFactory(notification -> {
            NotificationView<Message, MessageNotification> view = new NotificationView<>(notification);

            ImageView graphic = new ImageView(messageImage);
            graphic.setPreserveRatio(true);
            graphic.setFitWidth(48);
            view.setGraphic(graphic);

            return view;
        });

        messageGroup.getNotifications().add(new MessageNotification(new Message("Jane Doe", "Dinner tonight at 7 PM. Please don't be late!", ZonedDateTime.now())));
        // Add the message group to the info center
        infoCenterPane.getInfoCenterView().getGroups().add(messageGroup);

        // Groups are sorted by name by default, but you can customize the sorting order using the setSortOrder() method.
        messageGroup.setSortOrder(0);
        weatherGroup.setSortOrder(1);

        BorderPane content = new BorderPane();
        Button button = new Button("Create notifications!");
        content.setCenter(button);
        infoCenterPane.setContent(content);
        button.setOnAction(evt -> {
            Weather weather = new Weather(
                    ZonedDateTime.now(),
                    "Sunny",
                    "UV levels high today – wear sunscreen!",
                    "London, 15~24°C, light breeze"
            );
            WeatherNotification weatherNotification = new WeatherNotification(weather);
            weatherGroup.getNotifications().add(weatherNotification);

            // create a message notification
            messageGroup.getNotifications().add(new MessageNotification(new Message("John Doe", "Coffee break? Meet in the lounge at 3.", ZonedDateTime.now())));
        });

        StackPane root = new StackPane(infoCenterPane);
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setTitle("GemsFX Notifications");
        primaryStage.setScene(scene);
        primaryStage.show();

        PauseTransition pt = new PauseTransition(Duration.seconds(1));
        pt.setOnFinished(e -> {
            Weather zurichWeather = new Weather(
                    ZonedDateTime.now(),
                    "Clear skies",
                    "Ideal for outdoor photography.",
                    "Zurich, 15~20°C, light breeze."
            );
            WeatherNotification weatherNotification = new WeatherNotification(zurichWeather);
            weatherGroup.getNotifications().add(weatherNotification);
        });
        pt.play();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Step 6: Add Notification Actions for Messages

Add actions to the message notifications to allow users to respond to messages. e.g., "Reply" and "Delete".

image
import com.dlsc.gemsfx.infocenter.InfoCenterPane;
import com.dlsc.gemsfx.infocenter.Notification;
import com.dlsc.gemsfx.infocenter.NotificationAction;
import com.dlsc.gemsfx.infocenter.NotificationGroup;
import com.dlsc.gemsfx.infocenter.NotificationView;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.time.ZonedDateTime;
import java.util.Locale;

public class SimpleNotificationsApp extends Application {

    private final Image weatherImage = new Image("https://icons.iconarchive.com/icons/wineass/ios7-redesign/256/Weather-icon.png", true);

    public record Weather(ZonedDateTime time, String forecast, String tips, String details) {
    }

    public static class WeatherNotification extends Notification<Weather> {
        public WeatherNotification(Weather weather) {
            super(weather.forecast(), weather.details(), weather.time());
            setUserObject(weather);
        }
    }

    private final Image messageImage = new Image("https://icons.iconarchive.com/icons/wineass/ios7-redesign/256/Messages-icon.png", true);

    public record Message(String from, String content, ZonedDateTime time) {
    }

    public static class MessageNotification extends Notification<Message> {
        public MessageNotification(Message message) {
            super(message.from(), message.content(), message.time());

            //1. Create a replay action to the notification
            NotificationAction<Object> replyAction = new NotificationAction<>("Reply", notification -> {
                // This is where you would implement the reply logic. Maybe open a new window or dialog?
                System.out.println("Replying to message from " + message.from());
                // Hide the parent view and remove the notification from its group when the user clicks on it. This is the default behaviour.
                return OnClickBehaviour.HIDE_AND_REMOVE;
            });

            //2. Create a delete action to the notification
            NotificationAction<Object> deleteAction = new NotificationAction<>("Delete", notification -> {
                // This is where you would implement the delete logic. Maybe remove the message from the database?
                System.out.println("Deleting message ... ");
                // Remove the notification from its group when the user clicks on it.
                return OnClickBehaviour.REMOVE;
            });

            //3. Add the actions to the notification
            getActions().addAll(replyAction, deleteAction);
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        InfoCenterPane infoCenterPane = new InfoCenterPane();
        infoCenterPane.setStyle("-fx-background-color: white;");
        NotificationGroup<Weather, WeatherNotification> weatherGroup = new NotificationGroup<>("Weather");
        weatherGroup.setViewFactory(notification -> {
            NotificationView<Weather, WeatherNotification> view = new NotificationView<>(notification);
            ImageView graphic = new ImageView(weatherImage);
            graphic.setPreserveRatio(true);
            graphic.setFitWidth(48);
            view.setGraphic(graphic);
            Weather weather = notification.getUserObject();
            view.setContent(new Label(weather.tips()));
            return view;
        });

        infoCenterPane.getInfoCenterView().getGroups().add(weatherGroup);

        NotificationGroup<Message, MessageNotification> messageGroup = new NotificationGroup<>("Message");
        messageGroup.setViewFactory(notification -> {
            NotificationView<Message, MessageNotification> view = new NotificationView<>(notification);

            ImageView graphic = new ImageView(messageImage);
            graphic.setPreserveRatio(true);
            graphic.setFitWidth(48);
            view.setGraphic(graphic);

            return view;
        });

        messageGroup.getNotifications().add(new MessageNotification(new Message("Jane Doe", "Dinner tonight at 7 PM. Please don't be late!", ZonedDateTime.now())));
        infoCenterPane.getInfoCenterView().getGroups().add(messageGroup);

        messageGroup.setSortOrder(0);
        weatherGroup.setSortOrder(1);

        BorderPane content = new BorderPane();
        Button button = new Button("Create notifications!");
        content.setCenter(button);
        infoCenterPane.setContent(content);
        button.setOnAction(evt -> {
            Weather weather = new Weather(
                    ZonedDateTime.now(),
                    "Sunny",
                    "UV levels high today – wear sunscreen!",
                    "London, 15~24°C, light breeze"
            );
            WeatherNotification weatherNotification = new WeatherNotification(weather);
            weatherGroup.getNotifications().add(weatherNotification);

            messageGroup.getNotifications().add(new MessageNotification(new Message("John Doe", "Coffee break? Meet in the lounge at 3.", ZonedDateTime.now())));
        });

        StackPane root = new StackPane(infoCenterPane);
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setTitle("GemsFX Notifications");
        primaryStage.setScene(scene);
        primaryStage.show();

        PauseTransition pt = new PauseTransition(Duration.seconds(1));
        pt.setOnFinished(e -> {
            Weather zurichWeather = new Weather(
                    ZonedDateTime.now(),
                    "Clear skies",
                    "Ideal for outdoor photography.",
                    "Zurich, 15~20°C, light breeze."
            );
            WeatherNotification weatherNotification = new WeatherNotification(zurichWeather);
            weatherGroup.getNotifications().add(weatherNotification);
        });
        pt.play();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Common Method Reference

Notification

Method Description
setUserObject(T obj) Pass additional data to the NotificationView. Useful for transferring detailed information beyond basic notification content.
setExpanded(boolean expanded) Sets whether the notification's content area is expanded by default. Note: This setting is only relevant if a content area is defined.
setOnClick(OnClickBehaviour behaviour) Determines the response to click events on the notification. Possible values: NONE, REMOVE, HIDE, HIDE_AND_REMOVE. Default is HIDE_AND_REMOVE.
ObservableList<NotificationAction> getActions() A list of (optional) actions that the user can perform directly from within the notification.

NotificationView

Method Description
setGraphic(Node graphic) An (optional) node that will be used as the notification's graphic object / icon on the left-hand side.
setContent(Node content) An (optional) detailed UI that can be revealed interactively by the user.
setShowContent(boolean showContent) Determines whether the content area is visible.
setTimeConverter(StringConverter<ZonedDateTime> timeConverter) A converter that is used to convert the date and time of the notification into a human-readable text. The default converter creates a text like "now", "yesterday", "2 days ago", etc...

InfoCenterView

Method Description
setAutoOpenGroup(boolean autoOpenGroup) Groups can be opened automatically when a notification gets added to them. The default is false.
setNotificationSpacing(double notificationSpacing) Represents the spacing between individual notification views within the same notification group. This property allows adjustment of the vertical gap depending on the layout of the notification container. The default value is 10.0.
setPlaceholder(Node placeholder) A placeholder node that is shown when the info is empty. If null nothing will be displayed.
setExpandDuration(Duration expandDuration) The duration used for the expand / collapse animation when the view opens or closes a group.
setTransparent(boolean transparent) Determines whether the control will be transparent or not. By default, a semi-transparent black background is showing.
setShowAllFadeDuration(Duration showAllFadeDuration) The duration used for the animation when switching between the standard view and the "show all" view.
setShowAllGroup(NotificationGroup showAllGroup) The group that is currently being shown in the "show all" view of the control.
setSlideInDuration(Duration slideInDuration) The duration used for animating the slide-in / slide-out of a notification.
setOnShowAllGroupNotifications(Consumer<NotificationGroup<?, ?>> onShowAllGroupNotifications) A callback that gets invoked when the user presses the "show all" button of a group that has more than the maximum number of notifications linked to it. The default callback will switch to a list view control which will then be able to show all notifications of that group. Applications can choose to display the notifications in a different place, e.g. in a dialog.
ObservableList<NotificationGroup<?, ?>> getGroups()) A list of groups of notifications that will be visualized by the view. Every notification has to be a member of a group.
ObservableList<NotificationGroup<?, ?>> getUnmodifiablePinnedGroups() A read-only list of the currently pinned groups.
ObservableList<NotificationGroup<?, ?>> getUnmodifiableUnpinnedGroups() A read-only list of the currently unpinned groups.
ObservableList<Notification<?>> getUnmodifiableNotifications() A read-only list of all notifications of all groups currently added to the view.
ObservableList<Notification<?>> getUnmodifiablePinnedNotifications() A read-only list of all notifications of all pinned groups currently added to the view.
ObservableList<Notification<?>> getUnmodifiableUnpinnedNotifications() A read-only list of all notifications of all unpinned groups currently added to the view.
clearAll() Clears all notifications from all groups. But keeps the groups.

NotificationGroup

Method Description
setSortOrder(Integer sortOrder) Allows for custom sorting of notifications within the group. Groups are sorted by name by default.
setViewFactory(Callback<S, NotificationView<T, S>> viewFactory) Customizes the visual representation of notifications within the group.
setExpanded(boolean expanded) Sets whether the group is expanded by default. Groups are collapsed by default.
setShowHeader(boolean showHeader) Determines whether the group header is visible when the group is expanded. Recommended to be true.
setPinned(boolean pinned) Pinned groups will always be shown at the top of the info center. They can not be scrolled out of the visible area.
setMaximumNumberOfNotifications(int maximumNumber) A number that determines how many notifications can be shown in the group before the "show all" button will be accessible. When the user presses this button the info center will switch to a different layout and display only this group's notifications inside a ListView

InfoCenterPane

Method Description
setPinned(boolean pinned) A flag that can be used to pin the info center view so that it will not hide under any circumstances.
setContent(Node content) The content node will fill the entire width and height of the pane.
setShowInfoCenter(boolean showInfoCenter) The flag that controls whether the info center shall be shown or not.
setAutoHide(boolean autoHide) The flag that controls whether the info center shall be shown or not.
setAutoHideDuration(Duration autoHideDuration) A duration after which the pane will automatically hide the info center (if it isn't currently pinned and the mouse cursor is not on top of the info center).
setSlideInDuration(Duration duration) The duration used for the "slide in" / "slide out" animation when the info center view gets shown or hidden.
InfoCenterView getInfoCenterView() Get the InfoCenterView from the InfoCenterPane.

Additional References

  1. If you want to learn more about notification system, you can check the source code of relevant classes in the GemsFX project.
  2. For more complex examples, you can refer to the InfoCenterApp.