我已經幾次閱讀key bindings上的明確教程,但我的大腦緩存似乎不足以容納複雜的過程。 (不幸的是)匿名的Java工程師偶然發現了一個簡潔而熱鬧的javadoc,供私人包javax.swing.KeyboardManager
使用。Java如何派發KeyEvent?
我的問題是這樣的:除了最初檢查的KeyEventDispatcher
,描述是否遺漏和/或錯誤?
的KeyboardManager類用於爲 WHEN_IN_FOCUSED_WINDOW風格動作 幫助調度鍵盤操作。 其他條件下的操作是直接在JComponent中處理的 。
這裏的symantics 如何鍵盤調度 應該ATLEAST [原文]工作,我 理解[原文]的描述。
KeyEvents被分派到 的焦點組件。焦點經理 在處理此事件時首先得到解決。如果焦點管理者不想要 ,那麼JComponent調用 super.processKeyEvent()這允許 聽衆有機會處理 事件。
如果沒有一個聽衆「消耗」 事件,則鍵綁定獲得 鏡頭。這是開始 變得有趣的地方。首先,用WHEN_FOCUSED 條件定義的KeyStokes [sic]得到一個機會。如果沒有 這些想要的事件,然後 組件行走,雖然它的[sic]父母 尋找類型 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT的行動。
如果還沒有人接受它,那麼它 在這裏結束。然後,我們尋找 組件註冊爲 WHEN_IN_FOCUSED_WINDOW事件並激發 給他們。請注意,如果找不到這些 ,那麼我們會將該事件傳遞給菜單欄的 ,並讓它們在其上打開 。他們的處理方式不同。
最後,我們檢查我們是否在尋找內部框架的 。如果我們不是 需要事件,那麼我們將 移動到InternalFrame的創建者,如果有人想要事件( 等等),請參閱 。
(更新)如果你曾經想知道的鍵綁定引導這個大膽的警告:
因爲搜索組件的順序是不可預知的,避免重複WHEN_IN_FOCUSED_WINDOW綁定!
這是因爲該段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;
}
}
所以搜索的順序其實是預見,但顯然依賴於這種特定的實現,所以最好不依靠它根本就沒有。保持不可預測性。
(Javadoc和代碼是在WinXP jdk1.6.0_b105。)
這是對KeyEvent處理的一個很好的分析......但我不知道它是否真的是一個可以回答的問題。 – BoffinbraiN 2011-05-08 10:09:55
@BoffinbraiN:我希望有幾十個擺動徽章的人會說「就我所知,這是正確的」,這是最好的:) :) – 2011-05-09 13:47:23
是的,那肯定會更好!但是我認爲對於這個深度的東西,它確實是針對特定實現的,而且你比大多數勤奮的程序員都仔細地仔細審查了這個實現。 ;)當然,最好不要讓你的代碼依賴於這個特定的細節。 – BoffinbraiN 2011-05-09 16:41:42