Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add listeners to Swing components in Scala?

I'm trying to implement the MVC design pattern in a Rubik's cube Scala application.

In Java, I would do this by adding an ActionListener to the buttons with the listeners in the controller class. In Scala, I've found this extremely difficult. Can anyone give me some examples of how to do this?

like image 761
oscar Avatar asked Dec 16 '22 13:12

oscar


1 Answers

You can of course do it in the exact same way as you did in Java. Using Scala however, you can also use the Scala swing library to do this, which provides a set of wrappers around the Java Swing classes. It uses the concepts of publishers and reactors to observe and react to events. An introduction on the design of the library, including samples, can be found here.

The Publisher trait defines a publish(e: Event) method to notify all registered Reactors about an event. You can make any class a publisher by simply extending this trait, and call the publish method to publish your events. A reactor can be registered by using the method def listenTo(ps: Publisher), and deregistered by using def deafTo(ps: Publisher). When listening to a publisher, you can react to an event from this publisher by adding a reaction, which has the type PartialFunction[Event, Unit], as follows


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

  }

Here is some (fully incomplete) code using Scala-swing that hopefully provides you with an idea how to use this in a MVC pattern. Also you may want to check out the test package that is part of the library, where you can find a number of examples.


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)
  }  
}

The listenTo(button1) method in the form will notify the form about any button events. In this case it will react to the ButtonClicked event, which is an event that is defined in the scala-swing library. In this sample, the form just re-publishes the button event to some custom defined business event. The controller class in its turn listens to the form, and can react in an appropriate way to the business event.

like image 196
Arjan Blokzijl Avatar answered Dec 31 '22 17:12

Arjan Blokzijl