2012-06-25 14 views
5

Mi escena consiste solamente en ImageView, que muestra una imagen. Me gustaría fundir la imagen en negro (color asignado de la escena), luego, después de un tiempo, volver a difuminar de negro a la imagen. Encontré el FadeTransition muy apropiado para este propósito. Esta es una parte de mi código:¿Cómo esperar a que finalice una transición en javafx 2.1?

// fade to black transition 
    FadeTransition ft1 = new FadeTransition(Duration.millis(2000), myImageView); 
    ft1.setFromValue(1.0); 
    ft1.setToValue(0.0); 
    ft1.play(); 

    // fade from black transition 
    FadeTransition ft2 = new FadeTransition(Duration.millis(2000), myImageView); 
    ft2.setFromValue(0.0); 
    ft2.setToValue(1.0); 
    ft2.play(); 

Mi problema es que ft1.play() es asíncrona, por lo que el código de abajo comenzará a ser ejecutado antes de ft1.play() se sale. Como resultado, veo solo la segunda transición. ¿Cómo puedo esperar a que finalice la primera transición y luego iniciar la segunda transición? No puedo poner el hilo a dormir mientras tanto porque es el hilo principal de javafx (lo probé y no funcionó).

Intenté utilizar el método onFinishedProperty() con la combinación de una espera de un indicador, pero me atasco en el ciclo while para siempre. Aquí está mi código para eso:

boolean isTransitionPlaying; 
    FadeTransition ft = new FadeTransition(Duration.millis(2000), iv); 
    ft.setFromValue(1.0); 
    ft.setToValue(0.0); 
    ft.onFinishedProperty().set(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      transitionPlaying = false; 
     } 
    }); 
    transitionPlaying = true; 
    ft.play(); 

    while (transitionPlaying == true) 
    { 
     // busy wait 
     System.out.println("still waiting..."); 
    } 

    FadeTransition ft2 = new FadeTransition(Duration.millis(2000), iv); 
    ft2.setFromValue(0.0); 
    ft2.setToValue(1.0); 
    ft2.play(); 

¿Cómo se hace la espera correctamente? Gracias

Respuesta

3

de espera ocupada (o incluso Thread.sleep) en el subproceso de la aplicación JavaFX es siempre una mala idea - se ata el hilo que maneja el procesamiento de interfaz de usuario para que sus transiciones , así como el resto de su IU, nunca se actualiza, con lo que se congela la interfaz de usuario de su aplicación durante la agitada espera. Para una interfaz de usuario receptiva, debe ejecutar su lógica en el subproceso de la aplicación FX lo más rápido posible, luego deje pasar el subproceso para que el resto del sistema JavaFX pueda continuar con su procesamiento. Esta es la razón por la cual las transiciones tienen llamadas de retorno asíncronas, que, una vez que te acostumbras, son una forma muy natural de desarrollo.

Además de las soluciones de Uluk (que son geniales), también puede consultar la clase SequentialTransition para manejar la asistencia en la realización de transiciones en secuencia. Tenga en cuenta que si desea realizar una acción después de que SequentialTransition se haya completado, aún desea agregar un manejador de inicio de sesión a SequentialTransition para tomar medidas en ese momento.

+0

Supongo que estaba pensando que, dado que las transiciones play() son asincrónicas, suceden en otro hilo, luego en el hilo de la aplicación JavaFX. Esta es la razón por la que pensé que podría hacer que el hilo principal esperara a que las transiciones terminaran y luego reanudaran. Ahora veo que si el hilo de la aplicación está durmiendo, las transiciones tampoco se pueden procesar, ¿verdad? Así que supongo que SequentialTransition es la solución más clara para mi caso. Gracias a ti y a Ukuk ambos. – dadox

17

bien si su ft2 es el reflejo de la animación ft1 luego hacer

ft1.setAutoReverse(true); 
ft1.setCycleCount(1); 
// Or 
// ft1.setCycleCount(Timeline.INDEFINITE); 
// to loop infinitely (blinking effect) until stop() 

y usted no ft2. Si aún necesita ft2 a jugar después de ft1 continuación

ft1.setOnFinished(new EventHandler<ActionEvent>() { 

    @Override 
    public void handle(ActionEvent event) { 
     ft2.play(); 
    } 
}); 
+0

Ok, ¿conoces otra forma de ejecutar un código dado después de que la jugada() haya terminado, aparte de setOnFinished()? Me gustaría poder organizar las transiciones sobre mi código en lugar de organizar la lógica alrededor de las transiciones ... – dadox

+1

Desafortunadamente, como mencionaste, es difícil poner el hilo principal en modo de espera/dormir. La misma dificultad se plantea al mostrar la ventana de diálogo modal (confirmación). Pero el método showAndWait (v2.2) proporcionará la solución, que solo se aplica a las etapas modales. –

1

Tuve un problema donde otro código estaba haciendo algunos cálculos y quería ejecutar Animaciones en la aplicación JavaFX, pero necesitaba hacer otro código para esperar a que terminara la animación. Yo no era capaz de decir este otro código cuando la animación ha terminado, por lo que he creado método para la reproducción de Animación y luego esperar a que termine:

private synchronized void playAnimationAndWaitForFinish(final Animation animation) { 
    if (Platform.isFxApplicationThread()) { 
     throw new IllegalThreadStateException("Cannot be executed on main JavaFX thread"); 
    } 
    final Thread currentThread = Thread.currentThread(); 
    final EventHandler<ActionEvent> originalOnFinished = animation.getOnFinished(); 
    animation.setOnFinished(new EventHandler<ActionEvent>() { 

     @Override 
     public void handle(ActionEvent event) { 
      if (originalOnFinished != null) { 
       originalOnFinished.handle(event); 
      } 
      synchronized (currentThread) { 
       currentThread.notify(); 
      } 
     } 
    }); 
    Platform.runLater(new Runnable() { 

     @Override 
     public void run() { 
      animation.play(); 
     } 
    }); 
    synchronized (currentThread) { 
     try { 
      currentThread.wait(); 
     } catch (InterruptedException ex) { 
      //somebody interrupted me, OK 
     } 
    } 
} 

Se requiere que este método no se invoca en el principal JavaFX hilo, de lo contrario, funciona para mí.

Cuestiones relacionadas