Results 1 to 4 of 4
Like Tree1Likes
  • 1 Post By Fubarable

Thread: KeyListener and focus woes

  1. #1
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,060
    Rep Power
    6

    Default KeyListener and focus woes

    I've been experimenting with the InfoNode Docking Windows framework this weekend. Even though it's old and the mailing list is dead, it still seems to be one of the best available.

    The only problem is that when I use a component with a KeyListener as the child of a View, I'm having trouble getting my component focused so it can receive key events. The only thing I've found that works reliably is to add a MouseListener to my component which calls requestFocusInWindow() when the component is clicked. But then the user has to click it. I want my component to be focused when the dockable tab or panel it's in gains focus. The downside of InfoNode being so simple to use is that I didn't create those components myself; the framework did. I tried using a HierarchyListener to crawl the hierachy and get references to them, but focus listeners on those components didn't reliably fire when I needed them to.

    Any suggestions? (KeyBindings would be my last resort...)
    Get in the habit of using standard Java naming conventions!

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: KeyListener and focus woes

    Quote Originally Posted by kjkrum View Post
    Any suggestions? (KeyBindings would be my last resort...)
    Why? They're usually my first resort.
    DarrylBurke likes this.

  3. #3
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,060
    Rep Power
    6

    Default Re: KeyListener and focus woes

    Mainly because the component in question is a terminal, so I would have to add bindings for nearly every key on the keyboard. Plus, doesn't the component still have to be focused? Or, if I set bindings for when it's in the focused window, won't it interfere with other components' bindings?

    I tried the following approach to capture all keystrokes that weren't consumed by something else. It works, but either menu accelerators don't consume the keystrokes like they're supposed to (by returning true from postProcessKeyEvent(...)) or the KeyboardFocusManager doesn't stop traversing KeyEventPostProcessors when one of them does return true. If I have a menu with the mnemonic 'B' and I press Alt-B, the menu is opened but the code below still prints 'b'. (Oddly, if I press Alt-B to open the menu and then press 'B' again, the second 'b' does NOT reach my KeyEventPostProcessor...)

    Java Code:
    //		KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor() {
    		KeyboardFocusManager.setCurrentKeyboardFocusManager(new DefaultKeyboardFocusManager() {
    			@Override
    			public boolean postProcessKeyEvent(KeyEvent e) {
    				if (!e.isConsumed() && e.getID() == KeyEvent.KEY_TYPED) {
    					System.out.print(e.getKeyChar());
    				}
    				return true;
    			}
    		});
    Get in the habit of using standard Java naming conventions!

  4. #4
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,060
    Rep Power
    6

    Default Re: KeyListener and focus woes

    Well, this is what I've learned so far:

    JTextComponents modify their documents on a KEY_PRESSED event, but they don't consume it; instead, they consume the corresponding KEY_TYPED event. AbstractButtons (JButtons and JMenuItems) consume KEY_PRESSED events, but only if they have an action for that key.

    So you can identify all unconsumed KEY_PRESSED with a KeyEventPostProcessor, but there are a few caveats. First, you have to ignore KEY_PRESSED events if their target component is a JTextComponent. Second, all AbstractButtons need to have their processKeyBinding(...) method overridden like so:

    Java Code:
    			@Override
    			protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
    					int condition, boolean pressed) {
    				boolean consumed = super.processKeyBinding(ks, e, condition, pressed);
    				return consumed || (pressed && isSelected());
    			}
    This is rather hackish, so I'm still looking for a better solution. I'm hoping there's a better way to deal with focus buried somewhere in InfoNode's component properties.
    Get in the habit of using standard Java naming conventions!

Similar Threads

  1. KeyListener needs to grab focus!
    By sim18 in forum New To Java
    Replies: 2
    Last Post: 05-03-2013, 01:28 PM
  2. A KeyListener that doesn't require focus
    By vaano in forum New To Java
    Replies: 3
    Last Post: 11-14-2011, 10:46 PM
  3. Replies: 4
    Last Post: 10-30-2011, 07:52 AM
  4. Apache XML-RPC woes
    By wumpus in forum Networking
    Replies: 0
    Last Post: 08-17-2009, 03:15 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •