Is it possible to make a JComponent default to not-focusable?
I know you can call JComponent.setFocusable(false)
to make a Java component not be focusable. But since I have a 开发者_Python百科LOT of components in my application that I want to be that way, I was wondering if there is a simpler way than calling it on every one of dozens of objects. Like a UIDefaults
value?
I'm looking for this because my application runs full-screen and there is a KeyListener
on the JFrame
that listens for key strokes to trigger various events. But I found that whenever a JButton
or other added component is clicked it would get the focus and the key events would never reach the JFrame
. So a more elegant way to have key events be caught by a single parent container regardless of what child has the focus would also serve to fix my problem.
I was wondering if there is a simpler way than calling it on every one of dozens of objects.
I've never seen one.
there is a KeyListener on the JFrame that listens for key strokes to trigger various events.
Don't use a KeyListener.
Instead you can use JMenus and JMenuItems with accelerators. The benefit of this approach is that the key strokes are then document in the menus. See the section from the Swing tutorial on How to Use Menus.
Or if you don't like menus, then you should be using Key Bindings. They can be coded to work even if the component doesn't have focus.
Sounds like the job for a KeyEventDispatcher:
http://download.oracle.com/javase/6/docs/api/java/awt/KeyEventDispatcher.html
That would be solving the problem, not doctoring at not directly related properties with (incalculatable) side-effects :-)
How about:
public boolean getComponent(Container c)
{
Component[] cmps = c.getComponents();
for(Component cmp : cmps)
{
if(cmp instanceof JComponent) // or even you could specify the JComponent you want to make it not-focusable, for example (cmp instanceof JButton)
{
((JComponent)cmp).setFocusable(false);
return true;
}
if(cmp instanceof Container)
{
if(getComponent((Container) cmp)) return true;
}
}
return false;
}
Then just call it by:
getComponent(YourJFrame);
Here is a rather crude way of walking the tree and setting it on elements you care about. Just pass in a set of noFocus (or change the logic to just be everything)...
public static List<Component> disableFocus(final Container c, Set<Component> noFocus) {
Component[] comps = c.getComponents();
for (Component comp : comps) {
if (noFucus.contains(comp) { comp.setFocusable(false); }
if (comp instanceof Container) {
disableFocus(comp);
}
}
}
精彩评论