2016-11-30 49 views
0

是否可以在任意節點/區域/窗格上逐漸淡入淡出效果?JavaFX 8節點/區域/窗格上的背景色轉換

我只是想在VBox(包含標籤)上顯示細微/簡短的紅/白「閃光燈」效果,以便在標籤值發生變化時引起注意。

編輯:迄今爲止我發現的這種性質的所有例子似乎都使用了「形狀」(這是一個節點),但當然VBox或窗格不是形狀 - 所以不會幫助我太多。在VBox上調用getShape()只返回null,所以這沒有幫助(我猜佈局代碼還沒有執行)。

編輯2: 這幾乎可以工作,但是這個dang效果似乎完全覆蓋(我認爲)VBox中的所有內容,包括文本Label。

ColorInput effect = new ColorInput(0, 0, 900, 25, Paint.valueOf("#FFDDDD")); 

Timeline flash = new Timeline(
    new KeyFrame(Duration.seconds(0.4), new KeyValue(effect.paintProperty(), Paint.valueOf("#EED9D9"))), 
    new KeyFrame(Duration.seconds(0.8), new KeyValue(effect.paintProperty(), Paint.valueOf("#E0DDDD"))), 
    new KeyFrame(Duration.seconds(1.0), new KeyValue(effect.paintProperty(), Paint.valueOf("#DDDDDD")))); 
vbox.setEffect(effect); 
flash.setOnFinished(e -> vbox.setEffect(null)); 
flash.play(); 
+0

這是必須的,它是在一個VBox? –

+0

不一定,但它應該是一個容器或某種類型,以便它可以容納一個文本標籤。 – User

回答

2

最好的辦法是提供一個自定義動畫,像這樣(在Fabian的回答闡述):

@Override 
public void start(Stage primaryStage) { 

    Label label = new Label("Bla bla bla bla"); 

    Button btn = new Button("flash"); 
    VBox box = new VBox(10, label, btn); 
    box.setPadding(new Insets(10)); 

    btn.setOnAction((ActionEvent event) -> { 

     //************************** 
     //this animation changes the background color 
     //of the VBox from red with opacity=1 
     //to red with opacity=0 
     //************************** 
     final Animation animation = new Transition() { 

      { 
       setCycleDuration(Duration.millis(1000)); 
       setInterpolator(Interpolator.EASE_OUT); 
      } 

      @Override 
      protected void interpolate(double frac) { 
       Color vColor = new Color(1, 0, 0, 1 - frac); 
       box.setBackground(new Background(new BackgroundFill(vColor, CornerRadii.EMPTY, Insets.EMPTY))); 
      } 
     }; 
     animation.play(); 

    }); 

    Scene scene = new Scene(box, 100, 100); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 

} 
+0

看起來像成功! – User

1

您可以爲某個效果設置動畫效果,例如, DropShadow

@Override 
public void start(Stage primaryStage) { 
    Label label = new Label("Bla bla bla bla"); 

    DropShadow shadow = new DropShadow(); 
    shadow.setColor(Color.RED); 
    shadow.setSpread(0.75); 

    Timeline shadowAnimation = new Timeline(
      new KeyFrame(Duration.ZERO, new KeyValue(shadow.radiusProperty(), 0d)), 
      new KeyFrame(Duration.seconds(0.15), new KeyValue(shadow.radiusProperty(), 20d))); 
    shadowAnimation.setAutoReverse(true); 
    shadowAnimation.setCycleCount(2); 

    Button btn = new Button("flash"); 
    btn.setOnAction((ActionEvent event) -> { 
     Node target = label; 
     target.setEffect(shadow); 
     shadowAnimation.setOnFinished(evt -> target.setEffect(null)); 
     shadowAnimation.play(); 
    }); 

    VBox box = new VBox(10, label, btn); 
    box.setPadding(new Insets(10)); 

    Scene scene = new Scene(box, 100, 100); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

不錯的嘗試,讓它工作,但我認爲它仍然有點太微妙。我需要「閃光燈」在更大的屏幕區域,我認爲如果我不改變屏幕的更大區域,短消息仍然可能被忽略。 (具有諷刺意味的是,我知道這可以通過Adobe Flash/Flex實現,但是必須有一個合理的JFX解決方案!) – User

0

您可以創建一個假的外形和使用FillTransition插補申請形狀填充到控件背景。

public static void AnimateBackgroundColor(Control control, Color fromColor,Color toColor,int duration) 
{ 

    Rectangle rect = new Rectangle(); 
    rect.setFill(fromColor); 

    FillTransition tr = new FillTransition(); 
    tr.setShape(rect); 
    tr.setDuration(Duration.millis(duration)); 
    tr.setFromValue(fromColor); 
    tr.setToValue(toColor); 

    tr.setInterpolator(new Interpolator() { 
     @Override 
     protected double curve(double t) { 
      control.setBackground(new Background(new BackgroundFill(rect.getFill(), CornerRadii.EMPTY, Insets.EMPTY))); 
      return t; 
     } 
    }); 

    tr.play(); 
}