Responding to key events in scala
Asked Answered
D

5

6

I'm experimenting with a bit of Scala gui programming (my first project in scala, so I thought I'd start with something simple). But I seem to have got stuck at something that seems like it should be relatively trivial. I have a class that extends scala.swing.MainFrame, and I'd like to detect when a user presses a key when that window has focus. Funny thing is I don't seem to be able to find any way to get that event to fire.

I found an example of how someone else had got around the problem here: http://houseofmirrors.googlecode.com/svn/trunk/src/src/main/scala/HouseGui.scala but they seem to have reverted to using the Java Swing API, which is a little disappointing. Does anyone know if there's a more idiomatic way of intercepting events?

Dagny answered 28/6, 2010 at 21:58 Comment(0)
D
1

My solution for this required me to do the following:

class MyFrame extends MainFrame {

this.peer.addKeyListener(new KeyListener() {
    def keyPressed(e:KeyEvent) {
      println("key pressed")
    }

    def keyReleased(e:KeyEvent) {
      println("key released")
    }

def keyTyped(e:KeyEvent) {
      println("key typed")
    }
 })

}

This only seemed to work though if there were no button objects attached to this component, or any of it's children.

Dagny answered 30/6, 2010 at 8:46 Comment(0)
M
6

This seems to work with Scala 2.9

package fi.harjum.swing

import scala.swing._
import scala.swing.event._
import java.awt.event._

object KeyEventTest extends SimpleSwingApplication {
    def top = new MainFrame {
        val label = new Label {
            text = "No click yet"
        }
        contents = new BoxPanel(Orientation.Vertical) {
            contents += label
            border = Swing.EmptyBorder(30,30,10,10)
            listenTo(keys)
            reactions += {
                case KeyPressed(_, Key.Space, _, _) =>
                    label.text = "Space is down"
                case KeyReleased(_, Key.Space, _, _) =>
                    label.text = "Space is up"
            }
            focusable = true
            requestFocus
        }
    }
}      
Markus answered 5/8, 2012 at 15:8 Comment(0)
A
3

In addition to listening to this.keys you should also call requestFocus on the component or set focusable=true, if it is Panel or derived class.

Ambsace answered 8/10, 2011 at 17:56 Comment(0)
M
1

I expect you need to listen to this.keys (where this is the element of the GUI receiving the keyboard events). See the equivalent question about mouse event.

Mesh answered 29/6, 2010 at 4:40 Comment(3)
Thx Daniel, I needed this too. The scala's swing documentation is really poor.Alongshore
this.keys doesn't seem to be a valid attribute of scala.swing.MainFrame. Nor does this.Keys, this.Keyboard or this.keyboard. Is there any documentation on this anywhere?Dagny
@Dagny Not the MainFrame, but a Component: labels, panels, text areas, etc. And, of course, this refers to the component itself.Mesh
D
1

My solution for this required me to do the following:

class MyFrame extends MainFrame {

this.peer.addKeyListener(new KeyListener() {
    def keyPressed(e:KeyEvent) {
      println("key pressed")
    }

    def keyReleased(e:KeyEvent) {
      println("key released")
    }

def keyTyped(e:KeyEvent) {
      println("key typed")
    }
 })

}

This only seemed to work though if there were no button objects attached to this component, or any of it's children.

Dagny answered 30/6, 2010 at 8:46 Comment(0)
Q
0

Rather than falling back to java events all components have keys that publishes these events (so MainFrame does not). Not sure what the best solution is but it's always possible to wrap everything in the frame inside a Component and listen to its keys.

Queasy answered 20/10, 2011 at 7:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.