2013-07-16 24 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動畫,並且需要執行單個動畫步驟。我只是想澄清,如果您使用轉換,這不是必需的。 –