-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Bojan Vučinić wrote:
> Clint, Greg,
> Thanks for taking the time to look into this.
> Here is the code that works:
> def initButtons = {
> ...
> pressedDo(printButton, print)
> ...
> }
>
> def pressedDo (aB: PushButton, action: Unit) = {
> aB.getButtonPressListeners.add(new ButtonPressListener {
> override def buttonPressed(b: Button): Unit = action })
>
'print' is a function or method, right?
Try changing the signature of predded do from
def pressedDo (aB: PushButton, action: Unit)
to
def pressedDo (aB: PushButton, action: => Unit)
When you call the first version,
pressedDo(printButton, print)
print is actually invoked right then, instead of when the button is
pressed. The semantics for parameters of this type are the same as
Java's. The second version
def pressedDo (aB: PushButton, action: => Unit)
means that the second param is an anonymous function that takes no
parameters and returns Unit. Calling this version of pressedDo with
pressedDo(printButton, print)
correctly makes that function - in this case a function that takes no
params, calls 'print', and returns Unit - get called when the button is
pressed.
Now, when initButtons, and in turn pressedDo, is called, the window var
should be non-null, so the error you're seeing is weird. But the first
version of pressedDo, where print isn't called when the button is
pressed, is almost certainly not what you want. Fix that, and see what
happens.
> I get the error that display is null??
>
> It is really strange.
>
>
>
> Clint Gilbert said the following on 23/11/2010 20:37:
> Actually, the type of b is the problem:
>
> override def buttonPressed(b: Button): Unit = action
>
> or even
>
> override def buttonPressed(b: Button) = action
>
> instead of
>
> override def buttonPressed(b: PushButton): Unit = action
>
> is what you want.
>
> Clint Gilbert wrote:
>>>> This is getting off-topic, but it's something I actually know a tiny bit
>>>> about.
>>>>
>>>> The compiler is complaining (I think) because you're not actually
>>>> overriding buttonPressed. This can happen when type inference goes a
>>>> little astray, especially with methods that return Unit. Naming
>>>> buttonPressed's param 'b' shouldn't be a problem. I'd try explicitly
>>>> specifying the return type, like
>>>>
>>>> def pressedDo (aB: PushButton, action: Unit) = {
>>>> aB.getButtonPressListeners.add(new ButtonPressListener {
>>>> override def buttonPressed(b: PushButton): Unit = action
>>>> })
>>>> }
>>>>
>>>> There are also inference rule that take effect regarding the = in
>>>>
>>>> def foo(...) = { }
>>>>
>>>> vs def foo(...) { }
>>>>
>>>> The latter (I believe) is assumed to return Unit, but I always add the =
>>>> just to be sure. (/Programming Scala/ by Odersky, Venners, and Spoon
>>>> explains things like this very, very well.)
>>>>
>>>> Additionally, you probably want something like this:
>>>>
>>>> def pressedDo (aB: PushButton, action: => Unit) = {
>>>> aB.getButtonPressListeners.add(new ButtonPressListener {
>>>> override def buttonPressed(b: PushButton) = action
>>>> })
>>>> }
>>>>
>>>> Note the new type of the 'action' param. It's now "a function that
>>>> takes no params and returns Unit", instead of an actual value of type
>>>> Unit. This is an easy way to have lazily-evaluated parameters.
>>>>
>>>> Due to some neat syntactic sugar for writing anonymous functions of this
>>>> type, if you split the parameter list for pressedDo, like
>>>>
>>>> def pressedDo (aB: PushButton)(action: => Unit) = {
>>>> aB.getButtonPressListeners.add(new ButtonPressListener {
>>>> override def buttonPressed(b: PushButton) = action
>>>> })
>>>> }
>>>>
>>>> You could call it like:
>>>>
>>>> pressedDo(someButton) {
>>>> val foo = new Foo
>>>>
>>>> someOtherThing.doStuff(foo)
>>>>
>>>> //etc
>>>> }
>>>>
>>>> Here the stuff in the braces becomes an anonymous function that gets
>>>> passed to pressedDo.
>>>>
>>>> It's also possible to use implicit conversions (the perhaps
>>>> tastelessly-named "Pimp-My-Library" pattern[1]) to "add" the pressedDo
>>>> method to the Button class. Well, kind of, not really to the Button
>>>> class, but combined with the above technique, you could make a call like
>>>>
>>>> val someButton: Button = ...
>>>>
>>>> someButton pressed {
>>>> val foo = new Foo
>>>>
>>>> someOtherThing.doStuff(foo)
>>>> }
>>>>
>>>> which is starting to look smooth. Implicits can get pretty black-magic
>>>> though, so use them with care and restraint if you do.
>>>>
>>>> [1]: http://scala.sygneca.com/patterns/pimp-my-library
>>>>
>>>> Bojan Vu ini wrote:
>>>>> Hi All,
>>>>> If you are using Scala for your code then you are obliged to write
>>>>> listeners in the following way:
>>>>> printButton.getButtonPressListeners.add(new ButtonPressListener {
>>>>> override def buttonPressed(b: Button) {
>>>>> print
>>>>> }
>>>>> })
>>>>> I've tried to simplify this by defining the following method:
>>>>> def pressedDo (aB: PushButton, action: Unit) = {
>>>>> aB.getButtonPressListeners.add(new ButtonPressListener {
>>>>> override def buttonPressed(b: PushButton) { action }})
>>>>> }
>>>>> and than invoking the method in this way (example)
>>>>> pressedDo(printButton, print)
>>>>> however, this results in a compiler error:
>>>>> error: object creation impossible, since method buttonPressed in trait
>>>>> ButtonPressListener of type (x$1: org.apache.pivot.wtk.Button)Unit is not
>>>>> defined
>>>>> aB.getButtonPressListeners.add(new ButtonPressListener {
>>>>> I'm not a programming language specialist, and in addition a Scala
>>>>> novice, but I'm puzzled why putting boilerplate code in a separate method
>>>>> is not working??
>>>>> Best regards,
>>>>> Bojan
>>>>> Dr. Bojan Vu ini
>>>>> President, Ma-CAD<http://www.ma-cad.com/>
>>>>> [email protected]<mailto:[email protected]>
>>>>> IM: bvucinic (Skype)
>>>>> http://fr.linkedin.com/in/bvucinic
>>>>> Maintenance Concept Adjustment& Design 31, rue Chanzy
>>>>> Paris, Ile de France 75011 France
>>>>> Work: +33 (6) 14 15 36 70
>>>>> Mobile: +33 (6) 14 15 36 70
>>>>> Fax: +33 (1) 53 01 38 28
>>>>> See who we know in common<http://www.linkedin.com/e/wwk/4839994/>
>>>>> Want a signature like this?<http://www.linkedin.com/e/sig/4839994/>
>>
>>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkzsKEEACgkQ5IyIbnMUeTvZuACeNSx8S8WlJuKapvMUifzEyPFi
fuYAn2rDRNUzKa35nM9rbLXEnrj/ESKU
=uLdg
-----END PGP SIGNATURE-----