简体   繁体   中英

Background color transition on a JavaFX 8 Node/Region/Pane

Is it possible to do a simple background "flash" effect with a gradual fade on an arbitrary Node/Region/Pane?

I just want to show a subtle/brief red/white "flash" effect on a VBox (containing a label) to draw attention to it when the label's value changes.

Edit: All examples of this nature I've found so far seem to use a "Shape" (which is a Node), but of course a VBox or a Pane aren't a Shape - so that doesn't help me too much. Calling getShape() on the VBox just returns a null, so that's no help (I guess layout code hasn't been executed yet).

Edit 2: This ALMOST works, but this dang effect seems to be completely overwriting (I think) everything in the VBox, including the text Label.

ColorInput effect = new ColorInput(0, 0, 900, 25, Paint.valueOf("#FFDDDD"));

Timeline flash = new Timeline(
  new KeyFrame(Duration.seconds(0.4), new KeyValue(effect.paintProperty(), Paint.valueOf("#EED9D9"))),
  new KeyFrame(Duration.seconds(0.8), new KeyValue(effect.paintProperty(), Paint.valueOf("#E0DDDD"))),
  new KeyFrame(Duration.seconds(1.0), new KeyValue(effect.paintProperty(), Paint.valueOf("#DDDDDD"))));
vbox.setEffect(effect);
flash.setOnFinished(e -> vbox.setEffect(null));
flash.play();

Best way would be to provide a custom animation, like this (elaborating on fabian's answer):

@Override
public void start(Stage primaryStage) {

    Label label = new Label("Bla bla bla bla");

    Button btn = new Button("flash");
    VBox box = new VBox(10, label, btn);
    box.setPadding(new Insets(10));

    btn.setOnAction((ActionEvent event) -> {

        //**************************
        //this animation changes the background color
        //of the VBox from red with opacity=1 
        //to red with opacity=0
        //**************************
        final Animation animation = new Transition() {

            {
                setCycleDuration(Duration.millis(1000));
                setInterpolator(Interpolator.EASE_OUT);
            }

            @Override
            protected void interpolate(double frac) {
                Color vColor = new Color(1, 0, 0, 1 - frac);
                box.setBackground(new Background(new BackgroundFill(vColor, CornerRadii.EMPTY, Insets.EMPTY)));
            }
        };
        animation.play();

    });

    Scene scene = new Scene(box, 100, 100);

    primaryStage.setScene(scene);
    primaryStage.show();

}

You could animate a effect, eg DropShadow :

@Override
public void start(Stage primaryStage) {
    Label label = new Label("Bla bla bla bla");

    DropShadow shadow = new DropShadow();
    shadow.setColor(Color.RED);
    shadow.setSpread(0.75);

    Timeline shadowAnimation = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(shadow.radiusProperty(), 0d)),
            new KeyFrame(Duration.seconds(0.15), new KeyValue(shadow.radiusProperty(), 20d)));
    shadowAnimation.setAutoReverse(true);
    shadowAnimation.setCycleCount(2);

    Button btn = new Button("flash");
    btn.setOnAction((ActionEvent event) -> {
        Node target = label;
        target.setEffect(shadow);
        shadowAnimation.setOnFinished(evt -> target.setEffect(null));
        shadowAnimation.play();
    });

    VBox box = new VBox(10, label, btn);
    box.setPadding(new Insets(10));

    Scene scene = new Scene(box, 100, 100);

    primaryStage.setScene(scene);
    primaryStage.show();
}

You can create a fake shape and use the FillTransition Interpolator to apply the shape's fill to the control background.

public static void AnimateBackgroundColor(Control control, Color fromColor,Color toColor,int duration)
{

    Rectangle rect = new Rectangle();
    rect.setFill(fromColor);

    FillTransition tr = new FillTransition();
    tr.setShape(rect);
    tr.setDuration(Duration.millis(duration));
    tr.setFromValue(fromColor);
    tr.setToValue(toColor);

    tr.setInterpolator(new Interpolator() {
        @Override
        protected double curve(double t) {
            control.setBackground(new Background(new BackgroundFill(rect.getFill(), CornerRadii.EMPTY, Insets.EMPTY)));
            return t;
        }
    });

    tr.play();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM