Skip to content

Instantly share code, notes, and snippets.

@mucaho
Created February 13, 2014 10:42
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mucaho/8973013 to your computer and use it in GitHub Desktop.
Save mucaho/8973013 to your computer and use it in GitHub Desktop.
Akka Actors to be executed in Swing / JavaFX thread - based on Victor Klang's [Swing Actors](https://gist.github.com/viktorklang/2422443)
package akka.dispatch.gui
// original work copyright 2012 Viktor Klang
/**
* (A). define the gui dispatchers programmaticaly
*/
import akka.dispatch.{DispatcherPrerequisites, ExecutorServiceFactory, ExecutorServiceConfigurator}
import com.typesafe.config.Config
import java.util.concurrent.{ExecutorService, AbstractExecutorService, ThreadFactory, TimeUnit}
import java.util.Collections
import javax.swing.SwingUtilities
import javafx.application.Platform
// First we wrap invokeLater/runLater as an ExecutorService
abstract class GUIExecutorService extends AbstractExecutorService {
def execute(command: Runnable): Unit
def shutdown(): Unit = ()
def shutdownNow() = Collections.emptyList[Runnable]
def isShutdown = false
def isTerminated = false
def awaitTermination(l: Long, timeUnit: TimeUnit) = true
}
object JavaFXExecutorService extends GUIExecutorService {
override def execute(command: Runnable) = Platform.runLater(command)
}
object SwingExecutorService extends GUIExecutorService {
override def execute(command: Runnable) = SwingUtilities.invokeLater(command)
}
// Then we create an ExecutorServiceConfigurator so that Akka can use our JavaFXExecutorService for the dispatchers
class JavaFXEventThreadExecutorServiceConfigurator(config: Config, prerequisites: DispatcherPrerequisites) extends ExecutorServiceConfigurator(config, prerequisites) {
private val f = new ExecutorServiceFactory {
def createExecutorService: ExecutorService = JavaFXExecutorService
}
def createExecutorServiceFactory(id: String, threadFactory: ThreadFactory): ExecutorServiceFactory = f
}
// Then we create an ExecutorServiceConfigurator so that Akka can use our SwingExecutorService for the dispatchers
class SwingEventThreadExecutorServiceConfigurator(config: Config, prerequisites: DispatcherPrerequisites) extends ExecutorServiceConfigurator(config, prerequisites) {
private val f = new ExecutorServiceFactory {
def createExecutorService: ExecutorService = SwingExecutorService
}
def createExecutorServiceFactory(id: String, threadFactory: ThreadFactory): ExecutorServiceFactory = f
}
/**
* (B). Then we simply need to create a dispatcher configuration in our application.conf
*/
javafx-dispatcher {
type = "Dispatcher"
executor = "akka.dispatch.gui.JavaFXEventThreadExecutorServiceConfigurator"
throughput = 1
}
swing-dispatcher {
type = "Dispatcher"
executor = "akka.dispatch.gui.SwingEventThreadExecutorServiceConfigurator"
throughput = 1
}
// After that we just create the GUI Actors with a Props with the correct dispatcher set:
val javaFxActor = context.actorOf(Props[JavaFxActor].withDispatcher("javafx-dispatcher"), "javaFxActor")
val swingActor = context.actorOf(Props[SwingActor].withDispatcher("swing-dispatcher"), "swingActor")
// Done! Now all messages processed by the new actor will be executed by the Swing/JavaFX Event Dispatch Thread, enjoy!
@OlekRia
Copy link

OlekRia commented Sep 12, 2022

For archeologists :))))))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment