scala javafx javafx-2 akka scalafx

JavaFx2 o ScalaFx+Akka



javafx-2 (3)

¿Cómo ejecutar los actores Akka en una aplicación JavaFX / ScalaFX?

(Esta es una actualización de la pregunta basada en las primeras respuestas)

¿Es la solución compartir el mismo contexto de ejecución? ¿Significa tener los despachadores de actores basados ​​en el servicio de ejecución JavaFx? (Aquel con el que se ejecuta el código de manipulación de la interfaz de usuario)

¿Eso significa que un agente representaría la interfaz de usuario y podría manipularla? Quiero decir porque, como se sugiere a continuación, si un par de actores están en el servicio de ejecución de la interfaz de usuario, ¿no significa eso compartir un estado entre el agente (el objeto es la interfaz de usuario)?

¿Pueden 2 actores comunicarse mientras están en diferentes servicios de ejecutor? Estoy preguntando esto porque de lo que se sugiere a continuación, algún agente estaría en el Servicio del Ejecutor de UI mientras que otro no.

Finalmente, ¿por qué usar akka tal como está, con su contexto Executor diferente y usar Platform.runLater, podría tener alguna consecuencia en el rendimiento de la interfaz de usuario? Esto plantea la cuestión del servicio de varios ejecutores en la misma aplicación: ¿es eso malo?


Hay un par de cosas que debe considerar al usar varios subprocesos en JavaFX:

  • Cualquier código que termine de tocar el gráfico de la escena (por ejemplo, mediante la actualización de los datos vinculados a los controles) debe incluirse en Platform.runLater . Si usa la API de subprocesos múltiples incorporada en JavaFX (es decir, Task y Service ), esto se hará automáticamente, pero si usa cualquier otra utilidad de subprocesos múltiples, debe hacerlo usted mismo.

  • Su utilidad de subprocesos múltiples (es decir, Akka) debe (creo) que se le diga de alguna manera que deje algo de espacio para el hilo de eventos JavaFX. Si observa la fuente del Service , verá que tienen mucho cuidado al configurar el ejecutor. No estoy seguro de los detalles de esto, pero cuando experimenté con el uso de Scala''s Future s con JavaFX, observé cierta falta de respuesta en la interfaz de usuario cuando usé el ExecutionContext predeterminado, que desapareció cuando usé uno personalizado basado en la implementación del Service .

No hay soporte en ScalaFX (ni en ningún otro conjunto de herramientas) por trabajar con Scala Futures o Akka de una manera que te permita olvidarte de los dos puntos anteriores, pero seguramente sería interesante analizarlo.


Here es la esencia de los actores akka que se pueden ejecutar en el subproceso Swing o JavaFX. Es una extensión práctica y copiable de los Actores de Swing de Victor Klang basada en la respuesta de Rüdiger .


  • Futuros

La mejor manera de usar Scala Futures junto con un conjunto de herramientas de un solo hilo como JavaFX sería definir un ejecutor que le permita ejecutar futuros o actores en el hilo del Kit de herramientas de la interfaz de usuario.

El mismo problema existe para Swing, que también requiere que se realicen actualizaciones en el hilo del swing. A Viktor Klang se le ocurrió la siguiente solución Swing Execution Context . Aquí está traducido para JavaFX:

import akka.dispatch.ExecutionContext import javafx.application.Platform import java.util.concurrent.Executor // object JavaFXExecutionContext { implicit val javaFxExecutionContext: ExecutionContext = ExecutionContext.fromExecutor(new Executor { def execute(command: Runnable): Unit = Platform.runLater(command) }) }

Lo usarías así:

// import the default ec import scala.concurrent.ExecutionContext.Implicits.global // define the JavaFX ec so we can use it explicitly val fxec = JavaFXExecutionContext.javaFxExecutionContext future { // some asynchronous computation, running on the default // ForkJoin ExecutionContext because no ec is passed // explicitly }.map(result => { // update JavaFX components from result // This will run in the JavaFX thread. // Check Platform.isFxApplicationThread() to be sure! })(fxec)

El flujo de futuros puede ser muy complejo, siempre y cuando los pasos que interactúan con los componentes de JavaFX se estén ejecutando en el ExecutionContext de JavaFX.

Nota: depende de usted si hace que ForkJoin ec sea el valor predeterminado y pase la ecuación de JavaFX explícitamente o viceversa. Puede ser una buena idea hacer que el JavaFX ec sea el predeterminado para evitar errores y marcar las partes que pueden ejecutarse de forma asíncrona explícitamente con el ForkJoin ec.

  • Los actores

Para integrar un sistema basado en Actor con un kit de herramientas de UI de un solo hilo también hay una solución. Ver actores de swing . Todo lo que tienes que hacer es reemplazar el

SwingUtilities.invokeLater(command)

con

Platform.runLater(command)

y eres bueno para ir!

  • Cuando usar cual

Si tiene una aplicación de UI grande y solo desea escindir algunas operaciones asíncronas (cargar un archivo o hacer algún cálculo), probablemente sea preferible el enfoque basado en futuros. Pero tenga cuidado de no realizar ninguna interacción (ni leer ni escribir) con los componentes de JavaFX en los futuros que se ejecutan de forma asíncrona en el contexto de ejecución predeterminado.

Si tiene un sistema grande basado en actores y solo desea adjuntar una IU a algunas partes, probablemente sea preferible tener algunos actores que se ejecuten en el subproceso de JavaFX. YMMV.