2016-03-20 14 views
1

Folgendes ist ein SSCCE-Code; es funktioniert OK und die KeyListener reagiert richtig, aber das Hinzufügen einer JTextField zu JMenuBar bewirkt, dass die KeyListener überhaupt nicht reagiert.Das Hinzufügen von JTextField zu JMenuBar löscht KeyListener Antworten !! - Wie repariert man?

Runter zu uncomment/kommentieren Sie die Zeile, die einen JTextField sehen den Unterschied fügt hinzu: menuBar.add(textField);

import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JMenuItem; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 

public class JMenueWithKeyListenerExample extends JPanel { 

    JTextField textField; 
    JMenuBar menuBar; 
    JFrame f; 

    public JMenueWithKeyListenerExample() { 

     textField = new JTextField(); 

     menuBar = new JMenuBar(); 
     JMenu fileMenue = new JMenu("File"); 
     JMenuItem menuItem1 = new JMenuItem("Item 1"); 
     JMenuItem menuItem2 = new JMenuItem("Item 2"); 

     fileMenue.add(menuItem1); 
     fileMenue.add(menuItem2); 

     menuBar.add(fileMenue); 
     //menuBar.add(textField); // switch between comment & uncomment to see the difference 

     f = new JFrame(); 
     f.setJMenuBar(menuBar); 
     f.add(this); 

     f.addKeyListener(new KeyAdapter() { 

      @Override 
      public void keyPressed(KeyEvent e) { 
       if ((e.getKeyCode() == KeyEvent.VK_Z) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { 
        System.out.println("undo"); 
       } 
      } 
     }); 

     f.setSize(400, 400); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new JMenueWithKeyListenerExample(); 
      } 
     }); 
    } 
} 
+0

Warum nicht stattdessen action map/input map verwenden? –

+0

@SergeyTachenov - Eigentlich habe ich kein Beispiel gefunden, das zeigt, wie man Action Map/Input Map benutzt, um eine Kombination von Schlüsseln zu erreichen –

Antwort

3

Der bevorzugte Weg Shortcut-Tasten hinzuzufügen ist input map and action map zu verwenden, wie folgt aus:

f.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) 
     .put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_DOWN_MASK), 
      "Undo"); 
f.getRootPane().getActionMap() 
     .put("Undo", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("undo"); 
    } 
}); 

Natürlich sollten Sie in realem Code eine Konstante definieren, anstatt den Action-Namen "Undo" direkt zu codieren. Und vielleicht definieren Sie die Aktion separat, geben Sie einen richtigen Namen und andere nützliche Eigenschaften.