2011-11-16 44 views
7

幫助的標準組合鍵是命令 - 在mac上。我怎樣才能將這個組合鍵綁定到一個菜單項。如何綁定命令 - ?作爲幫助菜單的揮杆動作加速器?

注意:由於我們的用戶有不同的鍵盤佈局,我正在尋找一種解決方案,不需要關於什麼鍵「?」的知識。位於。

使用KeyStroke.getKeyStroke(String),javadoc說;

Parses a string and returns a `KeyStroke`. The string must have the following syntax: 

<modifiers>* (<typedID> | <pressedReleasedID>) 

modifiers := shift | control | ctrl | meta | alt | button1 | button2 | button3 
typedID := typed <typedKey> 
typedKey := string of length 1 giving Unicode character. 
pressedReleasedID := (pressed | released) key 
key := KeyEvent key code name, i.e. the name following "VK_". 

我有這樣的例子代碼:

import javax.swing.*; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 

public class HelpShortcut extends JFrame { 

    public HelpShortcut(){ 
     // A few keystrokes to experiment with 
     //KeyStroke keyStroke = KeyStroke.getKeyStroke("pressed A"); // A simple reference - Works 
     //KeyStroke keyStroke = KeyStroke.getKeyStroke("typed ?");  // Works 
     KeyStroke keyStroke = KeyStroke.getKeyStroke("meta typed ?"); // What we want - Does not work 

     // If we provide an invalid keystroke we get a null back - fail fast 
     if (keyStroke==null) throw new RuntimeException("Invalid keystroke"); 

     // Create a simple menuItem linked to our action with the keystroke as accelerator 
     JMenuItem helpMenuItem = new JMenuItem(new HelpAction()); 
     helpMenuItem.setAccelerator(keyStroke); 

     // Install the menubar with a help menu 
     JMenuBar mainMenu = new JMenuBar(); 
     JMenu helpMenu = new JMenu("Help"); 
     helpMenu.add(helpMenuItem); 
     mainMenu.add(helpMenu); 

     setJMenuBar(mainMenu); 
    } 

    // Scaffolding 
    public static void main(String[] pArgs) { 
     HelpShortcut helpShortcut= new HelpShortcut(); 
     helpShortcut.setLocationRelativeTo(null); 
     helpShortcut.setSize(new Dimension(100, 162)); 
     helpShortcut.setVisible(true); 
    } 

    private class HelpAction extends AbstractAction { 

     public HelpAction() { 
      putValue(Action.NAME,"Help me!"); 

     } 

     @Override 
     public void actionPerformed(final ActionEvent pActionEvent) { 
      JOptionPane.showMessageDialog(HelpShortcut.this,"You should ask StackOverflow!"); 
     } 

    } 
} 
+0

世界其他地方使用F1的幫助+1 – mKorbel

+1

這是真的,但命令 - ?是特定於應用程序的幫助的os x標準以及用戶期望的內容 - ref http://support.apple.com/kb/ht1343 另一個有趣的問題是,在較新的Mac上,缺省值是將F-鍵映射到特殊功能(聲音,亮度等),而不是「F1」等,這樣,如果用戶沒有在鍵盤偏好設置中啓用它們,這個快捷鍵將不會執行任何操作。 –

回答

6

在我的鍵盤 「?」高於「/」鍵,所以你也可以使用shift鍵鍵入「?」。因此,要做到結合你需要使用:

// KeyStroke keyStroke = KeyStroke.getKeyStroke("meta typed ?"); 
int modifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() 
      + KeyEvent.SHIFT_DOWN_MASK; 
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, modifier); 
+1

我有一個挪威的鍵盤,並且上面的問號是在「+」鍵的上面(在數字0的左邊 - 你使用KeyEvent.VK_PLUS建議的代碼不會做任何事情,如果你用VK_PLUS嘗試代碼,對於你(無視它不會映射到「?」)。另外 - 我怎樣才能避免必須知道鍵盤佈局? –

+0

有兩個鍵VK_PLUS和VK_ADD。在我的鍵盤上,VK_ADD是數字鍵盤上的鍵。不要以爲有一種方法可以知道鍵盤佈局,這是F1之類的鍵更安全的原因之一,我不知道這是如何在Mac世界中處理的,因爲我從來沒有使用Mac – camickr

+0

是的,我懷疑這是Mac上JRE的一個怪癖,並且可能很難找到解決方法,特別是在需要關於鍵盤佈局的知識時。感謝您的努力:-) –

3

(令人驚訝 - 我:-)改性劑keyIDs的綁定「類型」不支持:儘管你可以創建和綁定到這樣的InputMap中,它們是從來沒有找到,因爲鍵入keyEvents內部生成的keyStrokes使用keyChar並忽略修飾符。這種創作發生在JComponent.processKeyBindings(...)

boolean processKeyBindings(KeyEvent e, boolean pressed) { 
    if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) { 
     return false; 
    } 
    // Get the KeyStroke 
    KeyStroke ks; 

    if (e.getID() == KeyEvent.KEY_TYPED) { 
     ks = KeyStroke.getKeyStroke(e.getKeyChar()); 
    } 
    else { 
    ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(), 
       (pressed ? false:true)); 
    } 

關於它的思考,這可能是有意義的:按下/釋放處理物理按鍵,而類型化是最終的綜合「產量」一個或多個物理鍵。如果對於任何給定的組合沒有有效的keyChar,則不會生成keyTyped事件。基本問題是swing/awt開發人員衆所周知的美國中心主義:他們只把物理鍵看作是我們佈局中的那些物理鍵;-)沒辦法(我知道)得到其他鍵佈局不可知的方式。希望被證明是錯誤的

+0

謝謝,我應該考慮查看JDK代碼:)留下問題以查看是否有人有解決方法。 –

4

KeyEvent API doc - 說明部分:

並非所有的字符有一個與之相關的鍵碼。例如,問號沒有鍵碼,因爲沒有鍵盤出現在主層上。