Akka应用程序的GUI

时间:2015-09-02 14:26:50

标签: swing scala user-interface akka actor

我在Akka中创建了一个小应用程序,它有一个actor的层次结构(有一个ActorA有几个ActorB actor,而这些ActorB actor有几个ActorC actor)。现在我想添加一个小UI。此UI没有任何按钮,但只有一些标签在ActorC actor从其他actor接收某些消息时被修改。我的问题是我必须为每个ActorC actor创建一个标签,但是(ActorC actor的)数量并不总是相同的,所以我必须首先创建ActorC actor,然后我必须创建标签。我在Scala Swing上搜索过教程,但我刚刚找到了旧的文档或简单的例子,在我的情况下没用(比如按一下按钮做某事)。我甚至看到有几个人在他们的Akka应用程序中使用了Java Swing。我找到了一个名为Kamon的工具,但我需要创建一个界面,而不仅仅是监控我的演员。有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

不推荐使用Swing来支持JavaFX。也就是说,JavaFX允许您创建一个富有的客户端"应用。对于你想要的东西来说,这听起来太沉重了。

也许是一个简单的网页用户界面?你看过playframework.com吗?您的界面只是一些可以与演员交谈的网页。 Play和Akka很好地协同工作,使用可用的教程和模板开始使用Play非常容易。

答案 1 :(得分:1)

您的设计有两个方面。第一个方面是UI和工作演员之间的沟通。第二个是UI的操作。

场景可能是您的UI启动并启动Swing EDT线程以显示您的状态窗口。还创建了一个演员,它会向你的演员A伸出手,并说“准备好了”。 Actor A将消息转发给所有Actor B,然后将其转发给Actor Cs。然后,每个Actor C通过发送消息“我在这里”和“这是我的状态”来注册自己。

def receive = {
  ...
  case ReadyToGo =>
    myMonitor = sender
    sender ! "ready"
}

UI-Actor接收每个注册消息并将其映射到标签,并在需要时创建它。当每个Actor C更改其状态时,它会向UI-Actor发送一条新消息,说“我还在这里”和“这是我的状态”。

UI-Actor是Akka世界和UI的中间人。这是棘手的部分,因为UI-Actor在与Swing事件派发线程不同的线程上运行。它必须在Swing队列上放置一个任务,以便以线程安全的方式由Swing线程进行处理。一些粗略的代码:

// assume labelMap is a map from ActorRef to Label, ordered by insertion
def receive = {
  case IAmHere(status) =>
    val actorC = sender
    if ( ! (labelMap contains actorA) ) {
      addStatusLabel(actorC, status)
    }
  case IAmStillHere(status) =>
    updateStatusLabel(actorC, status)
}
def addStatusLabel(actorC: ActorRef, status: String) = {
  Swing.onEDT {
    labelMap(actorC) = new Label(status)
    // recalculate the panel size
    // repaint
  }
}
def updateStatusLabel(actorC: ActorRef, status: String) = {
  Swing.onEDT {
    labelMap(actorC).text = status
    // repaint
  }
}

我留给你布置UI,容器,状态是否为String,如何处理丢失的Actor C等。