2014-11-20 1 views
0

Я пытаюсь создать анимацию FadeIn/Out на окне (этапе). Если мышь перемещается на сцену, она должна затухать, и если мышь уходит, она должна исчезнуть.JavaFX 8 Изменение непрозрачности сцены не работает с StageStyle.TRANSPARENT (ошибка или моя ошибка?)

Я создал временную шкалу, которая изменяет stage.opacityProperty() для достижения этой цели. Я столкнулся с проблемами, когда установил стиль сцены прозрачным, как этот stage.initStyle(StageStyle.TRANSPARENT);. Если я это сделаю, исчезновение не будет видно. Временная шкала воспроизводит анимацию, но изменение непрозрачности не будет отображаться JavaFX. При настройке stageStyle по умолчанию все работает отлично, а окно и его оформление будут исчезать и исчезать.

Я хочу, чтобы этот эффект работал в стиле шага TRANSPARENT, поэтому я пробовал следующее: Я положил ярлык на сцену и изменил его текстовое свойство на другой временной шкале. Теперь я обновляю текст ярлыка каждые 400 мсек. Если я это сделаю, изменение непрозрачности будет отображаться при каждом изменении метки.

Это приводит меня к выводу, что изменение непрозрачности в стиле шага TRANSPARENT не приведет к перерисовке сцены. Изменение текста ярлыка приведет к перерисовке. Означает ли это, что я не могу угаснуть сцену в стиле сцены TRANSPARENT, если содержимое не изменится?

Является ли это ошибкой или я делаю что-то неправильно?

Я сделал SSCCE, который воспроизводит проблему. Если вы удалите строку stage.initStyle(StageStyle.TRANSPARENT);, анимация fadeIn/out будет работать гладко.

package de.schuette.jfx.stage_opacity_bug; 

import javafx.animation.KeyFrame; 
import javafx.animation.KeyValue; 
import javafx.animation.Timeline; 
import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.input.KeyCode; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 
import javafx.util.Duration; 

public class FadeApp extends Application { 
    public static void main(String[] args) { 
     Application.launch(args); 
    } 

    private Label label; 

    @Override 
    public void start(Stage stage) { 
     if (stage == null) 
      throw new IllegalArgumentException("No stage was set."); 

     this.label = new Label("HALLO WELT"); 

     Scene scene = new Scene(label, 300, 300); 

     scene.setOnKeyPressed(e -> { 
      if (e.getCode() == KeyCode.ESCAPE) { 
       stage.close(); 
      } 
     }); 

     stage.setScene(scene); 
     stage.setOpacity(1); 
     stage.initStyle(StageStyle.TRANSPARENT); 
     stage.setTitle("Opacity change does result in repaint when stage style is transparent."); 
     stage.setAlwaysOnTop(true); 
     stage.show(); 

     Platform.runLater(() -> { 

      Timeline t = new Timeline(new KeyFrame(Duration.millis(0), 
        new KeyValue(stage.opacityProperty(), 1)), new KeyFrame(
        Duration.millis(500), new KeyValue(stage.opacityProperty(), 
          0))); 
      t.setAutoReverse(true); 
      t.setCycleCount(Timeline.INDEFINITE); 

      t.playFromStart(); 
     }); 

     Platform.runLater(() -> { 

      Timeline t = new Timeline(new KeyFrame(Duration.millis(400), e -> { 
       label.textProperty().set(String.valueOf(Math.random())); 
      })); 
      t.setCycleCount(Timeline.INDEFINITE); 
      t.playFromStart(); 
     }); 
    } 

} 

Я currtently работает с

  • Java (TM) SE Runtime Environment (сборка 1.8.0_20-b26)
  • Windows 7 x64 Professional
+0

Вы можете добавить информацию о версии JavaFX и платформы, которую вы используете? – ItachiUchiha

+0

Я currtently работает с - Java (TM) SE Runtime Environment (сборка 1.8.0_20-B26) - Windows 7 x64 Professional К сожалению забыл его в должности. – UNIQUEorn

+0

Ваше приложение отлично работает для меня. Поведение с и без StageStyle.TRANSPARENT одинаково (только без него есть декоративная рамка для кнопок OS min/max, границы окна и т.д. вокруг окна). Протестировано на OS X 10.9.5, Oracle JDK 1.8.0_20-b26. Кстати, вам не нужны вызовы Platform.runLater в вашем коде, хотя он работает практически так же, как и без них. – jewelsea

ответ

0

С помощью разработчиков JavaFX мне удалось найти решение этой проблемы. Использование пользовательского линейного интерполятора, изменяющего свойство заливки сцены и немедленное изменение его первоначального значения, вызовет перерисовку на сцене. Это делается с помощью «bugFixInterpolator» в коде ниже:

package de.schuette.jfx.stage_opacity_bug; 

import javafx.animation.Interpolator; 
import javafx.animation.KeyFrame; 
import javafx.animation.KeyValue; 
import javafx.animation.Timeline; 
import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.input.KeyCode; 
import javafx.scene.paint.Color; 
import javafx.scene.paint.Paint; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 
import javafx.util.Duration; 

public class FadeApp extends Application { 
    public static void main(String[] args) { 
     Application.launch(args); 
    } 

    private Label label; 

    /* 
    * (non-Javadoc) 
    * 
    * @see javafx.application.Application#start(javafx.stage.Stage) 
    */ 
    @Override 
    public void start(Stage stage) { 
     if (stage == null) 
      throw new IllegalArgumentException("No stage was set."); 

     this.label = new Label("HELLO WORLD"); 

     Scene scene = new Scene(label, 300, 300); 

     scene.setOnKeyPressed(e -> { 
      if (e.getCode() == KeyCode.ESCAPE) { 
       stage.close(); 
      } 
     }); 

     stage.setScene(scene); 
     stage.setOpacity(1); 
     stage.initStyle(StageStyle.TRANSPARENT); 
     stage.setTitle("Opacity change does result in repaint when stage style is transparent."); 
     stage.setAlwaysOnTop(true); 
     stage.show(); 

     Interpolator bugFixInterpolator = new Interpolator() { 
      @Override 
      protected double curve(double t) { 
       Paint fill = scene.getFill(); 
       scene.setFill(Color.RED); 
       scene.setFill(fill); 
       return t; 
      } 

      @Override 
      public String toString() { 
       return "Interpolator.LINEAR"; 
      } 
     }; 

     Timeline t = new Timeline(new KeyFrame(Duration.millis(0), 
       new KeyValue(stage.opacityProperty(), 1, bugFixInterpolator)), 
       new KeyFrame(Duration.millis(500), new KeyValue(stage 
         .opacityProperty(), 0, bugFixInterpolator))); 
     t.setAutoReverse(true); 
     t.setCycleCount(Timeline.INDEFINITE); 
     t.playFromStart(); 

     t = new Timeline(new KeyFrame(Duration.millis(400), e -> { 
      label.textProperty().set(String.valueOf(Math.random())); 
     })); 
     t.setCycleCount(Timeline.INDEFINITE); 
     t.playFromStart(); 
    } 

}