Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you want to use Actors, following may work for you. </p> <p>There are two actors:</p> <ul> <li><em>WorkerActor</em> which does data processing (here, there is simple loop with Thread.sleep). This actor sends messages about progress of work to another actor:</li> <li><em>GUIUpdateActor</em> - receives updates about progress and updates UI by calling <em>handleGuiProgressEvent</em> method</li> </ul> <p>UI update method <em>handleGuiProgressEvent</em> receives update event. Important point is that this method is called by Actor using one of Akka threads and uses Swing.onEDT to do Swing work in Swing event dispatching thread. </p> <p>You may add following to various places to see what is current thread.</p> <pre><code>println("Current thread:" + Thread.currentThread()) </code></pre> <p>Code is runnable Swing/Akka application.</p> <pre><code>import akka.actor.{Props, ActorRef, Actor, ActorSystem} import swing._ import event.ButtonClicked trait GUIProgressEventHandler { def handleGuiProgressEvent(event: GuiEvent) } abstract class GuiEvent case class GuiProgressEvent(val percentage: Int) extends GuiEvent object ProcessingFinished extends GuiEvent object SwingAkkaGUI extends SimpleSwingApplication with GUIProgressEventHandler { lazy val processItButton = new Button {text = "Process it"} lazy val progressBar = new ProgressBar() {min = 0; max = 100} def top = new MainFrame { title = "Swing GUI with Akka actors" contents = new BoxPanel(Orientation.Horizontal) { contents += processItButton contents += progressBar contents += new CheckBox(text = "another GUI element") } val workerActor = createActorSystemWithWorkerActor() listenTo(processItButton) reactions += { case ButtonClicked(b) =&gt; { processItButton.enabled = false processItButton.text = "Processing" workerActor ! "Start" } } } def handleGuiProgressEvent(event: GuiEvent) { event match { case progress: GuiProgressEvent =&gt; Swing.onEDT{ progressBar.value = progress.percentage } case ProcessingFinished =&gt; Swing.onEDT{ processItButton.text = "Process it" processItButton.enabled = true } } } def createActorSystemWithWorkerActor():ActorRef = { def system = ActorSystem("ActorSystem") val guiUpdateActor = system.actorOf( Props[GUIUpdateActor].withCreator(new GUIUpdateActor(this)), name = "guiUpdateActor") val workerActor = system.actorOf( Props[WorkerActor].withCreator(new WorkerActor(guiUpdateActor)), name = "workerActor") workerActor } class GUIUpdateActor(val gui:GUIProgressEventHandler) extends Actor { def receive = { case event: GuiEvent =&gt; gui.handleGuiProgressEvent(event) } } class WorkerActor(val guiUpdateActor: ActorRef) extends Actor { def receive = { case "Start" =&gt; { for (percentDone &lt;- 0 to 100) { Thread.sleep(50) guiUpdateActor ! GuiProgressEvent(percentDone) } } guiUpdateActor ! ProcessingFinished } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload