2013-07-16 23 views
10

我想通过更改其样式类来更改Node的样式。如何在JavaFX中使用CSS制作动画?

Button button = new Button(); 
button.getStyleClass().add("class1") 
button.setOnMouseClicked(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      button.getStyleClass().add("class2"); 
     } 
    }); 

是否有可能逐渐改变风格,使之像过渡一样?

+0

除了你的问题:你为什么不使用花哨的LAMBDA标注在你的samplecode?你可以简单地写下:mouseEvent - > button.getStyleClass()。add(“class2”),而不是(新的Eventhan ...)。花式? – Sauer

回答

16

是否有可能逐渐改变风格,例如做一些转换?

是的。

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

当你想使用css来执行转换时,我只能真正推荐这种方法,因为没有相应的Java API易于使用。

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

例如,将您的样式属性绑定到字符串。然后在时间轴中更改要更改的组件(在本例中为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); 
    } 
} 
2

JavaFX2支持过渡。所以你不需要一步一步地制作你的动画。

看一看这样的: http://docs.oracle.com/javafx/2/animations/basics.htm#CJAJJAGI

+2

他问** ** **动画,而不是程序化动画 – specializt

+0

我知道。 Jewelsea提到,JavaFX不支持CSS动画,并且需要执行单个动画步骤。我只是想澄清,如果您使用转换,这不是必需的。 –