I have a TopComponent subclass that can have multiple instances which comes up
in editor mode. It contains a particular component, call it fc, that I always
want to be focused whenever this TopCompent is selected. I have overridden
requestActive() and componentActivated() to call fc.requestFocusInWindow() as
well as the super class methods. This seems to mostly work as desired: focus
goes where I want it to when the window is first realized, and it does fine with
switching among the tabbed instances as well.
However, if I close one instance, one of the sibling instances gets selected as
expected, but that instance does not respond to keyboard events until I click on
fc. Also, componentActivated() does get called, and the call to
fc.requestFocusInWindow() inside componentActivated() returns true. Even more
strangely, I added a FocusListener to fc to see what is going on, and it does
appear to get focus. A call to
also gives me back the component I want focused. Despite all this, keyboard
events still get ignored.
I found that I could get the focus behavior I want if I override
TopComponent.requestFocus() to call fc.getFocus(). Overriding
TopComponent.requestFocusInWindows() does not work. TopComponent.requestFocus()
is marked deprecated in the API, however. It seems to me that either this is a
documentation bug, i.e. that TopComponent.requestFocus() is really should not be
deprecated, but instead should be reserved solely for delegation of focus to
subcomponents, or else there's something subtlely going wrong with the focus
hand-off in the window system.
This module is running on the bare platform, not in the IDE, in case that makes
a difference. I'm developing in NB 5.5, but I also tried the 6.0m7 milestone and
saw the same behavior.
i don't think this is a bug. the javadoc for requestFocus and requestFocusInWindow methods respectively does give the
hint that these method should be overridden to transfer focus to desired focusable components.
the methods are deprecated because they shouldn't be invoked directly, the window manager should handle the focus
management so method requestActive should be used for focus transfer instead.
I would say that, at best, the javadoc is unclear on this point. I think that it should state clearly that it is fine to
override requestFocus() purely for managing the focus policy of subcomponents.
I still think that there is a bug here, though. Did you read the second paragraph of the report? It is my understanding
that calling fc.requestFocusInWindow() inside componentActivated() should be sufficient to focus the desired component
whenever my TC is selected. If my understanding is incorrect, I would appreciate a pointer to any relevant documentation
on how the window manager handles focus transfer.
Calling fc.requestFocusInWindow() inside componentActivated() does work as expected most of the time, but there are a
couple of use cases where focus does not get reassigned correctly. I have described one in that second paragraph, below,
involving closing of sibling tabs. I have just discovered another similar case:
(1) Open two of my editor windows in sibling tabs.
(2) Verify that that the topmost editor, call it tcA, responds to keypresses as expected.
(3) Click so focus moves to a different, unrelated, TopComponent.
(4) Click on the tab for the editor window that is currently NOT topmost, call it tcB, making it topmost.
(5) Type some keys and see what happens.
What happens is that that tcB comes forward and appears focused, but does not respond to the keypresses. If you switch
to the other instance, tcA, you will find that it actually received all of the keypresses!
the javadoc seems fine to me, but pls feel free to file a separate issue if you insist on rewording.
the window manager sometimes uses TopComponent.requestFocus() to transfer input focus (see ViewHierarchy.updateDesktop
and ModeContainer.focusSelectedTopComponent) so you should override both requestFocus and requestFocusInWindow.
all editor windows in netbeans IDE override both methods so your use case work fine in the IDE.