animation - 如何在 JavaFX 中使用 CSS 制作动画?

标签 animation user-interface javafx-2 javafx-8

我想改变Node的样式通过更改其样式类。

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 change style gradually, for example make some transition?



是的。

您将需要使用 setStyle 而不是样式类,因为类将是在 css 中定义的静态事物。 JavaFX css 中没有对动画的直接支持。您需要在 Java 代码中执行动画步骤来修改 css 样式。

只有当您想使用 css 执行转换时,我才会真正推荐这种方法,因为没有容易获得的相应 Java API。

要处理动画,可以使用标准的 javafx 动画 Timeline操作 css 样式属性所依赖的属性。

例如,将您的样式属性绑定(bind)到字符串。然后在时间轴中改变您想要更改的组件(在本例中为 colorStringProperty)。
warningButton.styleProperty().bind(
    new SimpleStringProperty("-fx-base: ")
        .concat(colorStringProperty)
        .concat(";")
        .concat("-fx-font-size: 20px;")
);

这是一个示例,它使用 css 闪烁按钮,按下时其基色从灰色到红色逐渐过渡。

warninggray
warningred
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 KeyValue(warningColor, Color.GRAY, Interpolator.LINEAR)),
                    new KeyFrame(Duration.seconds(1),    new KeyValue(warningColor, Color.RED,  Interpolator.LINEAR)),
                    new KeyFrame(Duration.seconds(1.25), new KeyValue(warningColor, Color.RED,  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);
    }
}

关于animation - 如何在 JavaFX 中使用 CSS 制作动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17676274/

相关文章:

javafx-2 - 热衷于动态更新字体大小

java - 是否可以设置 ProgressIndicator 的样式?

animation - 带队列的 CSS3 过渡

java - 我无法修复 GUI 的小问题。 JTextFields

css - 为通过 Canvas 绘制的星星的不透明度设置动画

user-interface - 编程中应采用哪些替代的用户输入技术?

javascript - Material-UI 中的单选按钮组

java - 在 TextField 中选择一个词

matplotlib 中的动画与分散和使用 set_offsets : Autoscale of figure is not working

android:如何动画翻译LayerDrawable的单层