Search code examples
cssjavafxtransitionfade

JavaFX trouble with fade transitions


I'm currently developing an app. It's visual structure is the following:

  • Only one Stage.
  • Only one Scene which has an ApplicationContainer's (my own class which is basically a StackPane with a BorderPane inside of it with a MenuBar on top, and the current page in it's center).
  • Multiple ApplicationLayout's

The ApplicationLayout has a Header and a Footer (footer not implemented yet) and looks like this:

enter image description here

I've managed to implement fadeIn / fadeOut transitions between the pages by setting a StackPane as the BorderPane's center, adding the page to it, and on top of that, a white VBox. So before I make the page switch I work with FadeTransitions of this white VBox.

I had to do it this way because setOpacity() wouldn't change the textfields or button opacities for some reason.

Now I'm trying to do the exact same thing for the header. So I setted a StackPane to the top, and added to it the header and a on top of it a "header coverer" which supposedly should do the trick just as before (can't modify the opacity property of the title, arrow or description because of CSS overriding).

But this time it's not working, if I set the opacity of the header coverer to anything but 0, the stuff in the header doesn't show.

What I want to acomplish is to fadeOut / FadeIn the components of the header but not the orange HBox.

EDIT: Added a minimal example where this doesn't work for me

Capture2

public class Main extends Application {


    private Boolean buttonPressed = false;


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

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

        BorderPane appWindow = new BorderPane();
        appWindow.setStyle("-fx-alignment: center; -fx-padding: 30 0 0 30");
        appWindow.setBackground(new Background(new BackgroundFill(Color.PERU, null, null)));
        GridPane loginContainer = new GridPane();
        appWindow.setCenter(loginContainer);

        TextField username = new TextField();
        PasswordField password = new PasswordField();
        Label userNameDesc = new Label("Username");
        Label passwordDesc = new Label("Password");
        Button logInBtn = new Button("Log In");

        logInBtn.setTranslateX(100);
        logInBtn.setTranslateY(20);

        logInBtn.setOnAction(event -> {

            if (!buttonPressed) {
                appWindow.getCenter().setOpacity(30);
                buttonPressed = true;
                System.out.println("Opacity set to " + appWindow.getCenter().getOpacity());
            }

            else {
                appWindow.getCenter().setOpacity(100);
                buttonPressed = false;
                System.out.println("Opacity set to " + appWindow.getCenter().getOpacity());
            }

        });

        loginContainer.addColumn(0, userNameDesc, passwordDesc);
        loginContainer.addColumn(1, username, password);
        loginContainer.add(logInBtn, 1, 2);

        Scene scene = new Scene(appWindow, 300, 250);
        stage.setScene(scene);
        stage.show();
    }
}

Pressing the "Log In" button should affect the Gridpane and Gridpane childs visual opacity, but it doesn't. It just prints the correct opacity values.


Solution

  • According to the documentation:

    Opacity is specified as a value between 0 and 1. Values less than 0 are treated as 0, values greater than 1 are treated as 1.

    So setting the value to 30 or to 100 has no effect: both are treated as fully opaque (i.e. they are clamped at 1).

    Replacing

    appWindow.getCenter().setOpacity(30);
    

    with

    appWindow.getCenter().setOpacity(0.3);
    

    will make the center content partially transparent.