2011-11-16 18 views
7

La combinación de teclas estándar para obtener ayuda es comando - ? en Mac. ¿Cómo puedo vincular esta combinación de teclas a un elemento de menú?Cómo enlazar comando-? como un acelerador de acción de swing para un menú de ayuda?

Nota: Como nuestros usuarios tienen diferentes diseños de teclado, estoy buscando una solución que no requiera el conocimiento sobre qué tecla "?" está ubicado en.

Usando KeyStroke.getKeyStroke(String), que javadoc dice;

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_". 

que tienen este código de ejemplo:

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

resto del mundo use F1 para Ayuda +1 – mKorbel

+1

Eso es cierto, pero comando-? es el estándar os x para la ayuda específica de la aplicación y lo que los usuarios esperarían - ref http://support.apple.com/kb/ht1343 Otro problema interesante es que en los nuevos Macs, el valor predeterminado es tener las teclas F asignadas a funciones especiales (sonido, brillo, etc.) y no "F1", etc. para que este atajo no haga nada sin que el usuario lo habilite en las preferencias del teclado. –

Respuesta

6

en mi teclado el "?" está arriba de la tecla "/", así que también usa la tecla Mayús para escribir "?". Así que para hacer la unión es necesario utilizar:

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

Tengo un teclado noruego, y en él el questionmark está encima de la tecla "+" (a la izquierda del número 0 - su código sugerido con KeyEvent.VK_PLUS no hace nada. Si prueba el código con VK_PLUS, ¿funciona? para usted (sin tener en cuenta que no se asignará a "?"). Además, ¿cómo puedo evitar tener que saber sobre el diseño del teclado? –

+0

Hay dos teclas VK_PLUS y VK_ADD. En mi teclado, VK_ADD es la clave en el teclado numérico. No creo que haya una manera de hacerlo, sino conocer el diseño del teclado. Esa es una de las razones por las que las teclas como F1 son más seguras de usar. No sé cómo se maneja esto en un mundo de Mac ya que nunca he usado una Mac – camickr

+0

Sí, sospecho que esto es una peculiaridad del JRE en Mac y que podría ser difícil encontrar una solución, especialmente cuando se necesita conocimiento sobre el diseño del teclado. Gracias por su esfuerzo :-) –

3

(sorprendentemente - a mí :-) modificadores a las consolidaciones de keyIDs "escrito" no son compatibles: mientras que se puede crear y vincular a dicha al inputMap, son nunca encontrado porque las pulsaciones de teclas generadas internamente para keyEvents escritos utilizan keyChar e ignoran los modificadores. Eso sucede en la creación 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)); 
    } 

Pensando en ello, que puede tener sentido: presionado/liberado maneja las teclas físicas, mientras que mecanografiada es la final "rendimiento" combinado de uno o más físico llaves. Si no existe un keyChar válido para una combinación determinada, no se genera ningún evento KeyTyped.

El problema de base es el conocido centrismo usa de los desarrolladores de swing/awt: contaban como claves físicas solo aquellas en el diseño de nosotros ;-) De ninguna manera (que yo sepa) para obtener otras claves en un disposición de manera agnóstica. La esperanza de estar equivocado

+0

Gracias, debería haber pensado en mirar el código JDK :) Dejando la pregunta abierta para ver si alguien tiene una solución alternativa. –

4

Ver KeyEvent API doc - toma nota de la sección:

No todos los personajes tienen un código clave asociada con ellos. Por ejemplo, no hay un código clave para el signo de interrogación porque no hay un teclado para el que aparezca en la capa primaria.

Cuestiones relacionadas