2
votes

I'm a beginner in JavaFX. I'm trying to create my own Button subclass that would have its on animations for mouse enter and mouse exit. The animation I'm trying to achieve is a simple "darken" or "dim" transition that would darken the color of the button background when user hovers over the button , and would animate back to normal state when the mouse exits the button.

First I thought I can achieve this with FillTransition, but for that I would need the specific darker color of the button, that depends on the button color. So now I'm trying to basically fade in and fade out a low-opacity black rectangle on top of the button, but the rectangle doesn't seem to appear at all.

Here's the code of my button:

public class FlatButton extends Button {

    private Rectangle dimRectangle;
    private Duration dimDuration = Duration.millis(250);
    private Color dimColor = new Color(0,0,0,0.11);

    public FlatButton(String text) {
        super(text);

        getStyleClass().addAll("flat-button-style");
        createEffect();
    }

    private void createEffect() 
    {
        dimRectangle = new Rectangle(this.getWidth(), this.getHeight(), dimColor);
        dimRectangle.setOpacity(1.0);
        dimRectangle.setX(this.get);


        FadeTransition enterTransition = new FadeTransition(dimDuration, this);
        enterTransition.setInterpolator(Interpolator.EASE_OUT);
        enterTransition.setFromValue(0.0);
        enterTransition.setToValue(1.0);

        FadeTransition exitTransition = new FadeTransition(dimDuration, this);
        exitTransition.setInterpolator(Interpolator.EASE_OUT);
        exitTransition.setFromValue(1.0);
        exitTransition.setToValue(0.0);


        this.setOnMouseEntered(new EventHandler<MouseEvent>(){

            public void handle(MouseEvent mouseEvent){
                enterTransition.play();
            }
        });

        this.setOnMouseExited(new EventHandler<MouseEvent>(){

            public void handle(MouseEvent mouseEvent){
                exitTransition.play();
            }
        });
    }

}

EDIT: The part in the code "new FadeTransition(dimDuration, this);" should be "new FadeTransition(dimDuration, dimRectangle);". It's just something I was testing.

EDIT2: I figured that "dimRectangle = new Rectangle(this.getWidth(), this.getHeight(), dimColor);" is not really working , but I havent found a way yet how to make the rectangle fill the button dimensions.

1
Unless it's outside this code, you don't seem to actually add dimRectangle anywhere on the scenegraph?Michael Berry
No it's not outside the code. Can I add it somehow directly in this button class ? I was kind of following this material ripple effect code: github.com/nonameplum/md-button-fx-sample/blob/master/src/main/… It doesn't seem to be added there to the scene graph either.Near
I can't see how that's added into the scenegraph in that code either. The route I would go down would be to add both that and the Button to a StackPane, you should then be able to setMouseTransparent() on the rectangle and fade in the same way.Michael Berry

1 Answers

3
votes

You could use a ColorAdjust effect and change it's brightness property using a Timeline.

public class ButtonFadeDemo extends Application {

    @Override
    public void start(Stage primaryStage) {

        try {

            Pane root = new Pane();

            Button button = new Button("Click me!");

            ColorAdjust colorAdjust = new ColorAdjust();
            colorAdjust.setBrightness(0.0);

            button.setEffect(colorAdjust);

            button.setOnMouseEntered(e -> {

                Timeline fadeInTimeline = new Timeline(
                        new KeyFrame(Duration.seconds(0), 
                                new KeyValue(colorAdjust.brightnessProperty(), colorAdjust.brightnessProperty().getValue(), Interpolator.LINEAR)), 
                                new KeyFrame(Duration.seconds(1), new KeyValue(colorAdjust.brightnessProperty(), -1, Interpolator.LINEAR)
                                ));
                fadeInTimeline.setCycleCount(1);
                fadeInTimeline.setAutoReverse(false);
                fadeInTimeline.play();

            });

            button.setOnMouseExited(e -> {

                Timeline fadeOutTimeline = new Timeline(
                        new KeyFrame(Duration.seconds(0), 
                                new KeyValue(colorAdjust.brightnessProperty(), colorAdjust.brightnessProperty().getValue(), Interpolator.LINEAR)), 
                                new KeyFrame(Duration.seconds(1), new KeyValue(colorAdjust.brightnessProperty(), 0, Interpolator.LINEAR)
                                ));
                fadeOutTimeline.setCycleCount(1);
                fadeOutTimeline.setAutoReverse(false);
                fadeOutTimeline.play();

            });

            root.getChildren().addAll(button);

            Scene scene = new Scene(root, 800, 400);
            primaryStage.setScene(scene);
            primaryStage.show();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


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