1

I would like to display a NotificationPane after certain user actions. My application has multiple scenes and the NotificationPane should be showed up in the currently active scene.

The whole thing works with Notification, it pops up when I need it. But I can't figure out how to make this work for NotificationPane.

Steps I made so far:

  • I tryed to put NotificationPane directly to my scene and call show() - it works.
  • Now the Idea is to get the current pane by calling stage.getScene().getRoot(), wrap it to NotificationPane and then call show() - it doesn't work and I have no idea why.
  • ((BorderPane) pane).setCenter(new Label("TEST")); this line is replacing buttons with text label, so stage.getScene().getRoot() is returning the right object

I made a simple program to test the behaviour. One button to call NotificationPane. Any suggestions?

Here is my test program:

package application;

import org.controlsfx.control.NotificationPane;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        Button notificationPaneButton = new Button("NotificationPane");
        notificationPaneButton.setOnAction(e -> showNotificationPane(primaryStage, "Notification text"));

        VBox vbox = new VBox(5);
        vbox.setAlignment(Pos.CENTER);
        vbox.getChildren().addAll(notificationPaneButton);

        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(vbox);

        primaryStage.setTitle("Notifications test");
        primaryStage.setScene(new Scene(borderPane, 300, 200));
        primaryStage.show();
    }

    public void showNotificationPane(Stage stage, String message) {
        Parent pane = stage.getScene().getRoot();
//      ((BorderPane) pane).setCenter(new Label("TEST"));
        NotificationPane notificationPane = new NotificationPane(pane);
        notificationPane.setText(message);
        if (notificationPane.showingProperty().get()) {
            notificationPane.hide();
            System.err.println("hide");
        } else {
            notificationPane.show();
            System.err.println("show");
        }

    }
}

1 Answers1

1

Ok, I see the problem now. Wrapping current pane is not enough, I also have to add the NotificationPane to the scene. Right?

Anyway my current solution is following:

  • get current scene
  • get current pane
  • wrap pane
  • replace current scene with the new one

To avoid wrapping NotificationPane multiple times I check if current pane is already a NotificationPane and then call show().

public void showNotificationPane(Stage stage) {
    Scene scene = stage.getScene();
    Parent pane = scene.getRoot();
    if (!(pane instanceof NotificationPane)){
        NotificationPane notificationPane = new NotificationPane(pane);
        scene = new Scene(notificationPane, scene.getWidth(), scene.getHeight());
        stage.setScene(scene);
        notificationPane.show();
    } else {
        ((NotificationPane)pane).show();
    }
}