Взаимодействие с акторами в приложениях scala swing

Я пишу небольшое приложение на scala. Приложение обрабатывает простые файлы журналов. Поскольку обработка занимает некоторое время, я решил позволить ядру моего приложения расширить Actor.

class Application extends Actor {
  def react() {
    loop {
      react {
        case Process(file) => // do something interesting with file...
      }
    }
  }
}

Обработка файла журнала запускается нажатием кнопки в графическом интерфейсе. В графическом интерфейсе используется Scala Swing.

object Gui extends SimpleSwingApplication {
  val application = new Application().start()

  def top = new MainFrame {
    val startButton = new Button

    reactions += {
      case ButtonClicked(`startButton`) => application ! Process(file)
    }
  }
}

Теперь ядро ​​приложения должно уведомлять графический интерфейс о текущем прогрессе.

  sender ! Progress(value) // whenever progress is made

Я решил эту проблему, создав отдельный актер внутри графического интерфейса. Актер выполняется внутри потока edt. Он слушает сообщения от ядра приложения и обновляет графический интерфейс.

  object Gui extends SimpleSwingApplication {
    val actor = new Actor {
      override val scheduler = new SchedulerAdapter {
        def execute(fun: => Unit) { Swing.onEDT(fun) }
      }
      start()

      def act() {
        loop {
          react {
            case ForwardToApplication(message) => application ! message
            case Progress(value) => progressBar.value = value
          }
        }
      }
    }
  } 

Поскольку ядро ​​приложения должно знать об отправителе сообщения, я также использую этого актора для пересылки сообщений из графического интерфейса в ядро ​​приложения, делая моего актора новым отправителем.

  reactions += {
    case ButtonClicked(`startButton`) => actor ! ForwardToApplication(Process(file))
  }

Этот код работает отлично. Мой вопрос: Есть способ сделать это попроще? Было бы неплохо просто использовать механизм реакции для сообщений моего приложения:

  reactions += {
    case Progress(value) => progressBar.value = value
  }

Есть идеи, как этого добиться?

9
задан Daniel Seidewitz 6 January 2011 в 13:42
поделиться