如何在Scala中为Swing组件添加监听器?

4
我正在尝试在一个魔方Scala应用程序中实现MVC设计模式。
在Java中,我会通过将监听器添加到控制器类中的按钮上来完成此操作。在Scala中,我发现这非常困难。有人能给我一些如何做到这一点的示例吗?
1个回答

12
当然,您可以像在Java中一样以完全相同的方式执行此操作。但是,使用Scala,您还可以使用Scala Swing库来完成此操作,该库提供了一组包装器,用于包装Java Swing类。它使用publishersreactors的概念来观察和响应事件。有关库设计的介绍,包括示例,请参见此处Publisher特征定义了一个publish(e: Event)方法,以通知所有已注册的Reactor有关事件的信息。您可以通过简单扩展此特征来使任何类成为发布者,并调用发布方法来发布您的事件。可以使用def listenTo(ps: Publisher)方法注册反应器,使用def deafTo(ps: Publisher)方法取消注册。当监听发布者时,可以通过添加类型为PartialFunction[Event, Unit]的反应来对来自此发布者的事件做出反应,如下所示。

  class MyComponent {
    listenTo(publisher)
    reactions += {
      case e: MyEvent => println("Got event " + e)
    }

  }

这里是使用Scala-swing编写的一些(完全不完整的)代码,希望能为您提供如何在MVC模式下使用它的想法。此外,您可能还想查看库的测试包,其中包含许多示例。


import scala.swing
import scala.swing.event._

case object MyBusinessEvent extends Event

class MyController extends Publisher {
    val form = new MyForm
    listenTo(form)
    reactions += {
      case MyBusinessEvent => //handle event code here
    }
}

class MyForm extends Publisher {
  val ui = new GridBagPanel {
    val c = new Constraints
    .... more code here
  }

  val button1 = new Button("Button 1") 
  //add button to panel


  listenTo(button1) 
  reactions += {
    case ButtonClicked(_) => publish(MyBusinessEvent)
  }  
}

表单中的listenTo(button1)方法将通知表单有关任何按钮事件的信息。在这种情况下,它将对ButtonClicked事件做出反应,这是在scala-swing库中定义的事件。在此示例中,表单只是将按钮事件重新发布到一些自定义的业务事件中。控制器类依次监听表单,并可以以适当的方式对业务事件做出反应。

这个问题和答案之间的质量差异最大,我投给它了! - Duncan McGregor
好的,谢谢您的帮助。我尝试了几件事情,但仍然没有运气。我已将它移出了MainFrame,但仍然遇到相同的错误。模式类型与预期类型不兼容;找到:对象rubik.MyEvent,需要:scala.swing.event.Event。 - oscar
@oscar:你的自定义事件需要继承自Event trait,就像错误信息所说的那样。我已经更新了示例。 - Arjan Blokzijl
在完成其余按钮的代码时,我发现了一个新错误。我为应用程序的第二个按钮创建了一个名为“b2Event”的新事件,并使用其自己的publish(b2Event)方法,但是我得到了错误:unreachable code。 如果将case b2Event=>这一行删除,b2按钮的反应与b1按钮相同……有什么建议吗? - oscar
我已经修改了代码如下:sealed abstract class Evento(val id: Int )extends Event {} case object B1Event extends Evento(0) case object B2Event extends Evento(1) class RubikUI (modelo : modRubik, factory:Factory)extends Publisher{ 现在我不再收到编译器错误,但是button2仍然重定向到button1的行为。如果您需要查看项目,请点击此处链接 - oscar
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接