Update: Forget about EditDone
. See Update below!scala.swing.TextField
is a basic GUI component that can be used for
letting the user input a line of text. When listening to this component, one can react to an EditDone
event:
// Inside some GUI component ...
val textField = new TextField(20)
contents += textField
listenTo(textField)
reactions += {case EditDone(`textField`) =>
println("Ok, searching DB for input "+ textField.text)
}
//...
Fine. Whenever the user (me) hits the Enter key, the message, "Ok,
searching for DB input ...", simulating a database search, is printed.
However, what happens when some unrelated software product suddenly
pops up a window while the user (me) is still inputting text into the
TextField? I tell you what: The evil, non-sentient contraption prints
the simulated search message --- just as if I had hit Enter.
When the TextField loses focus, it emits an EditDone event. But I'm
not done editing. I've only typed "a". I was about to type
"abecedarian". Now the silly thing will search the database for all
words containing the letter "a". I never told it to do that. This
happened just because some other, unrelated, ill-behaving program
grabbed the focus.
Of course, the focus may also be lost because the user voluntarily
changes windows (for instance, in order to Google for "abecedarian").
As far as I can tell, there is no sane way to tell an EditDone event
produced by the user (me) hitting Enter from an EditDone event
produced because the TextField component lost focus. This cannot be
right.
(A while ago, I asked about this on the Scala-user list. Not one single
answer from one single soul in the entire Universe. It feels lonely.)
(I'm using Scala 2.8.)
Update: Forget about
EditDone
.What you should do, is not to listen to the
TextField
, but to TextField.keys
. This way, you'll be able to catch a KeyPressed
event, and check if the key pressed was Enter
. Simple.It's a bit tricky to figure out, however, since it's not in the
TextField
Scala docs (you'll have to find your way to scala.swing.Component
). This is how it could look:import swing._
import event._
//...
// Inside some GUI component ...
val textField = new TextField(20)
contents += textField
listenTo(textField.keys)
import Key._
reactions += {case KeyPressed(`textField`, Enter, _, _) =>
println("Ok, searching DB for input "+ textField.text)
}
//...
Thanks to Ingo Maier for explaining this.