java中keyevent,Java如何调度KeyEvent?

I've read the definite tutorial on key bindings a few times, but my brain cache doesn't seem large enough to hold the complicated processes.

I was debugging a key binding problem (turned out I was using the wrong JComponent.WHEN_* condition), and I stumbled upon a concise and hilarious javadoc for the package private javax.swing.KeyboardManager by an (unfortunately) anonymous Java engineer.

My question is this: except for KeyEventDispatcher which is checked at the very beginning, does the description miss and/or mistake anything?

The KeyboardManager class is used to

help dispatch keyboard actions for the

WHEN_IN_FOCUSED_WINDOW style actions.

Actions with other conditions are

handled directly in JComponent.

Here's a description of the symantics

[sic] of how keyboard dispatching

should work atleast [sic] as I

understand it.

KeyEvents are dispatched to the

focused component. The focus manager

gets first crack at processing this

event. If the focus manager doesn't

want it, then the JComponent calls

super.processKeyEvent() this allows

listeners a chance to process the

event.

If none of the listeners "consumes"

the event then the keybindings get a

shot. This is where things start to

get interesting. First, KeyStokes

[sic] defined with the WHEN_FOCUSED

condition get a chance. If none of

these want the event, then the

component walks though it's [sic] parents

looked for actions of type

WHEN_ANCESTOR_OF_FOCUSED_COMPONENT.

If no one has taken it yet, then it

winds up here. We then look for

components registered for

WHEN_IN_FOCUSED_WINDOW events and fire

to them. Note that if none of those

are found then we pass the event to

the menubars and let them have a crack

at it. They're handled differently.

Lastly, we check if we're looking at

an internal frame. If we are and no

one wanted the event then we move up

to the InternalFrame's creator and see

if anyone wants the event (and so on

and so on).

(UPDATE) If you've ever wondered about this bold warning in the key bindings guide:

Because the order of searching the components is unpredictable, avoid duplicate WHEN_IN_FOCUSED_WINDOW bindings!

It's because of this segment in KeyboardManager#fireKeyboardAction:

Object tmp = keyMap.get(ks);

if (tmp == null) {

// don't do anything

} else if ( tmp instanceof JComponent) {

...

} else if ( tmp instanceof Vector) { //more than one comp registered for this

Vector v = (Vector)tmp;

// There is no well defined order for WHEN_IN_FOCUSED_WINDOW

// bindings, but we give precedence to those bindings just

// added. This is done so that JMenus WHEN_IN_FOCUSED_WINDOW

// bindings are accessed before those of the JRootPane (they

// both have a WHEN_IN_FOCUSED_WINDOW binding for enter).

for (int counter = v.size() - 1; counter >= 0; counter--) {

JComponent c = (JComponent)v.elementAt(counter);

//System.out.println("Trying collision: " + c + " vector = "+ v.size());

if ( c.isShowing() && c.isEnabled() ) { // don't want to give these out

fireBinding(c, ks, e, pressed);

if (e.isConsumed())

return true;

}

}

So the order of searching is actually predictable, but obviously dependent on this particular implementation, so it's better not to rely on it at all. Keep it unpredictable.

(Javadoc and code is from jdk1.6.0_b105 on WinXP.)

解决方案

We need to start debugging from Component.dispatchEventImpl.

Just reading through the source comments of the method should give you the perfect idea of how events flow in Swing(you can also start one level up from EventQueue.pumpEventsForHeirarchy).

For clarity just let me give an extract from the code:

Set timestamp and modifiers of current event.; Pre-dispatchers. Do any necessary retargeting/reordering here before we notify AWTEventListeners.

Allow the Toolkit to pass this event to AWTEventListeners.

If no one has consumed a key event, allow the KeyboardFocusManager to process it.

Allow input methods to process the event

Pre-process any special events before delivery

Deliver event for normal processing

Special handling for 4061116 : Hook for browser to close modal dialogs.:)

Allow the peer to process the event. Except KeyEvents, they will be processed by peer after all KeyEventPostProcessors (see DefaultKeyboardFocusManager.dispatchKeyEvent())

Now you can match the above flow with your description to determine whether its right or not. But the point is you should really not depend on javadocs of private classes, the reason being that the developers usually dont care to update the comments of private classes when code changes, so the docs may become obsolete.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值