Реагирование на ключевые события в Scala

я экспериментирую с немного программирования Scala gui (мой первый проект в scala, поэтому я думал, что начну с чего-то простого). Но я, кажется, застрял в чем-то, что кажется, должно быть относительно тривиальным. У меня есть класс, который расширяет скала.качать.Мейнфрейм, и я хотел бы определить, когда пользователь нажимает клавишу, когда это окно имеет фокус. Забавно, что я, похоже, не могу найти способ заставить это событие сработать.

Я нашел пример того, как кто-то другой обошел проблему здесь:http://houseofmirrors.googlecode.com/svn/trunk/src/src/main/scala/HouseGui.scala но они, похоже, вернулись к использованию API Java Swing, что немного разочаровывает. Кто-нибудь знает, есть ли более идиоматические способ перехвата событий?

5 ответов


это, кажется, работает с 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
        }
    }
}      

В дополнение к прослушиванию this.keys вы также должны вызвать requestFocus на компоненте или установить focusable=true, если это Panel или производный класс.


Я ожидаю, что вам нужно слушать this.keys (где this является элементом GUI, получающим события клавиатуры). См. эквивалентный вопрос о событие мыши.


мое решение для этого потребовало от меня сделать следующее:

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

}

Это только казалось, что работает, хотя, если бы не было объектов button, прикрепленных к этому компоненту или любому из его детей.


вместо того, чтобы возвращаться к событиям java, все компоненты имеют keys который публикует эти события (so MainFrame нет). Не уверен, что лучшее решение, но всегда можно обернуть все в рамку внутри Component и слушать ее keys.