I'd like to use a timer in a Scala Swing application. I can use the Java version, only it means I have to implement the ActionListener interface. I'd rather use the Scala Publishers / Reactors model for consistency, so I can have things that listenTo
the timer.
Here's what I tried:
class ScalaTimer(time: Int) extends Component {
val t = new javax.swing.Timer(time, new java.awt.event.ActionListener {
def actionPerformed(e: java.awt.event.ActionEvent) {
publish(new scala.swing.event.ActionEvent(this))
}
})
def start() {t.start()}
def stop() {t.stop()}
// etc
}
Doesn't work because this
refers to the the ActionListener rather than the ScalaTimer class.
Also I probably shouldn't be extending Component
... I tried this because I get the Publisher / Reactor functionality, but it doesn't really make sense. Should I do something like this instead? If so, are there other traits I need to include, and how do I know which methods I have to implement?
class ScalaTimer extends javax.swing.Timer with Publisher {
(My IDE immediately flags "Missing arguments for method Timer(Int, ActionListener)" which seems a bit weird since I haven't invoked a method.)
Tom is correct: you can use
ScalaTimer.this
.Timer(Int, ActionListener)
is the constructor ofTimer
, which you have invoked. You need to writeextends javax.swing.Timer(constructor_args)
. Of course, the constructor arguments may depend on constructor arguments forScalaTimer
.You would be able to achieve this in Java thus: ScalaTimer.this
It's probably the same in Scala
The canonical way to do this is to introduce an alias at the top of the thing you want to refer to (usually
self
unless that's already taken):Simple wrapper:
Use:
I had to tackle this recently as well and this seems to work for me:
You could also override other methods to provide for better encapsulation, but this is functional as is.