Added Keyboard.listener().

Also factored some shared code into KeyboardImpl.