How to use CSS in JavaFX to animate?
I want to change the style of the node by changing its style class
Button button = new Button(); button.getStyleClass().add("class1") button.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent mouseEvent) { button.getStyleClass().add("class2"); } });
Is it possible to gradually change style and transform?
Solution
Yes
You will need to use setstyle instead of style classes, because classes will be static events defined in CSS There is no direct support for animation in JavaFX CSS You need to perform animation steps in Java code to modify CSS styles
When you want to use CSS to perform transformation, I only really recommend this method, because there is no corresponding Java API that can be easily obtained
To handle animation, you can use the standard JavaFX animation timeline to handle the properties that CSS style properties depend on
For example, bind your style properties to strings Then change the component to be changed in the timeline (colorstringproperty in this case)
warningButton.styleproperty().bind( new SimpleStringProperty("-fx-base: ") .concat(colorStringProperty) .concat(";") .concat("-fx-font-size: 20px;") );
This is an example. It uses CSS to flash a button. When pressed, its basic color gradually changes from gray to red
import javafx.animation.*; import javafx.application.Application; import javafx.beans.property.*; import javafx.beans.value.*; import javafx.event.*; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.image.*; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.stage.Stage; import javafx.util.Duration; /** Shows how you can modify css styles dynamically using a timeline. */ public class Warning extends Application { private static final String BACKGROUND = "http://bobgreiner.tripod.com/1cc2ce10.jpg"; @Override public void start(Stage stage) throws Exception{ final ObjectProperty<Color> warningColor = new SimpleObjectProperty<>(Color.GRAY); final StringProperty colorStringProperty = createWarningColorStringProperty(warningColor); StackPane layout = new StackPane(); layout.getChildren().addAll( new ImageView(new Image(BACKGROUND)),createWarningButton( warningColor,colorStringProperty ) ); stage.setScene(new Scene(layout)); stage.show(); } private StringProperty createWarningColorStringProperty(final ObjectProperty<Color> warningColor) { final StringProperty colorStringProperty = new SimpleStringproperty(); setColorStringFromColor(colorStringProperty,warningColor); warningColor.addListener(new changelistener<Color>() { @Override public void changed(ObservableValue<? extends Color> observableValue,Color oldColor,Color newColor) { setColorStringFromColor(colorStringProperty,warningColor); } }); return colorStringProperty; } private Button createWarningButton(final ObjectProperty<Color> warningColor,StringProperty colorStringProperty) { final Button warningButton = new Button("Warning! Warning!"); warningButton.styleproperty().bind( new SimpleStringProperty("-fx-base: ") .concat(colorStringProperty) .concat(";") .concat("-fx-font-size: 20px;") ); warningButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent actionEvent) { Timeline flash = new Timeline( new KeyFrame(Duration.seconds(0),new KeyValue(warningColor,Color.GRAY,Interpolator.LINEAR)),new KeyFrame(Duration.seconds(0.25),new KeyFrame(Duration.seconds(1),Color.RED,new KeyFrame(Duration.seconds(1.25),Interpolator.LINEAR)) ); flash.setCycleCount(6); flash.setAutoReverse(true); flash.play(); } }); return warningButton; } private void setColorStringFromColor(StringProperty colorStringProperty,ObjectProperty<Color> color) { colorStringProperty.set( "rgba(" + ((int) (color.get().getRed() * 255)) + "," + ((int) (color.get().getGreen() * 255)) + "," + ((int) (color.get().getBlue() * 255)) + "," + color.get().getOpacity() + ")" ); } public static void main(String[] args) { launch(args); } }