This uses the alternative approach suggested by Slaw in the comments:
you could also animate the background color. Though it's a little complicated, since you can't animate the background property directly. You have to animate the color and set the background yourself every time the color changes (Color implements Interpolatable).
I also would prefer Giovanni's solution over this. This solution is mainly offered as an example of how you might create a custom transition.
There are two solutions provided.
The key to these solutions is the same in both cases, extend Transition
and override the interpolate method to set the required background fill for a given interpolation value.
Interpolates between two colors (the start color and a transparent color).
protected void interpolate(double frac) {
Color cur = from.interpolate(to, frac);
target.setBackground(BackgroundUtil.createBackground(cur));
}
OR
Interpolates just the opacity portion of a single color.
protected void interpolate(double frac) {
Color cur = Color.color(
color.getRed(),
color.getGreen(),
color.getBlue(),
color.getOpacity() * frac
);
target.setBackground(BackgroundUtil.createBackground(cur));
}
Executable Example
The output of the example is similar to the screenshot in Giovanni's solution.
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class BackgroundFade extends Application {
@Override
public void start(Stage stage) throws Exception {
Button testButton = new Button("Test");
testButton.setStyle("-fx-background-color: green;");
Pane pane = new Pane(testButton);
pane.setPrefSize(500, 500);
pane.setBackground(
BackgroundUtil.createBackground(Color.RED)
);
//applyBackgroundColorTransition(pane);
applyBackgroundOpacityTransition(pane);
stage.setScene(new Scene(pane));
stage.show();
}
private void applyBackgroundColorTransition(Pane pane) {
BackgroundColorTransition backgroundColorTransition = new BackgroundColorTransition(
Duration.seconds(5),
pane,
Color.RED,
Color.TRANSPARENT
);
backgroundColorTransition.setCycleCount(Transition.INDEFINITE);
backgroundColorTransition.setAutoReverse(true);
backgroundColorTransition.play();
}
private void applyBackgroundOpacityTransition(Pane pane) {
BackgroundOpacityTransition backgroundOpacityTransition = new BackgroundOpacityTransition(
Duration.seconds(5),
pane,
Color.RED
);
backgroundOpacityTransition.setCycleCount(Transition.INDEFINITE);
backgroundOpacityTransition.setAutoReverse(true);
backgroundOpacityTransition.play();
}
}
class BackgroundColorTransition extends Transition {
private final Region target;
private final Color from;
private final Color to;
public BackgroundColorTransition(Duration duration, Region target, Color from, Color to) {
setCycleDuration(duration);
this.target = target;
this.from = from;
this.to = to;
}
@Override
protected void interpolate(double frac) {
Color cur = from.interpolate(to, frac);
target.setBackground(BackgroundUtil.createBackground(cur));
}
}
class BackgroundOpacityTransition extends Transition {
private final Region target;
private final Color color;
public BackgroundOpacityTransition(Duration duration, Region target, Color color) {
setCycleDuration(duration);
this.target = target;
this.color = color;
}
@Override
protected void interpolate(double frac) {
Color cur = Color.color(
color.getRed(),
color.getGreen(),
color.getBlue(),
color.getOpacity() * frac
);
target.setBackground(BackgroundUtil.createBackground(cur));
}
}
class BackgroundUtil {
public static Background createBackground(Color color) {
return new Background(
new BackgroundFill(
color, null, null
)
);
}
}