Why can't I get KeyEvent.VK_TAB when I use Key Binding for a JPanel

前端 未结 3 1741
轻奢々
轻奢々 2021-01-20 22:45

I will print related info if users focus on current window and press a key. However, it works for some keys like \'a\' but not for \'tab\'. Here is a simple demo:

         


        
3条回答
  •  不要未来只要你来
    2021-01-20 23:04

    Quote from How to Use the Focus Subsystem (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features) (suggested by @alex2410(link to @camickr post) and @mKorbel):

    In most Look and Feel models, components are navigated using the Tab and Shift-Tab keys. These keys are the default focus traversal keys and can be changed programmatically.
    ...
    Tab shifts the focus in the forward direction. Shift-Tab moves the focus in the backward direction. Tabbing moves the focus through the buttons into the text area. Additional tabbing moves the cursor within the text area but not out of the text area because, inside a text area, Tab is not a focus traversal key. However, Control-Tab moves the focus out of the text area and into the first text field. Likewise, Control-Shift-Tab moves the focus out of the text area and into the previous component.
    ...
    The Control key is used by convention to move the focus out of any component that treats Tab in a special way, such as JTable.
    You have just received a brief introduction to the focus architecture. If you want more details, see the specification for the Focus Subsystem.

    So if you want to make the Tab KeyBinding action work in the panel, you need to remove the Tab key focus navigation from the panel.

    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    
    //http://stackoverflow.com/q/24800417/714968
    public class KeyBindingTest3 {
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() {
            createAndShowGUI();
          }
        });
      }
      public static void createAndShowGUI() {
        JFrame f = new JFrame("KeyBinding Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new MainPanel());
        f.setSize(320, 240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    }
    
    class MainPanel extends JPanel {
      public MainPanel() {
        super();
        //@see JTable constructor
        Set forwardKeys = new HashSet(1);
        forwardKeys.add(KeyStroke.getKeyStroke(
            KeyEvent.VK_TAB, InputEvent.CTRL_MASK));
        setFocusTraversalKeys(
            KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
    
        Set backwardKeys = new HashSet(1);
        backwardKeys.add(KeyStroke.getKeyStroke(
            KeyEvent.VK_TAB, InputEvent.SHIFT_MASK | InputEvent.CTRL_MASK));
        setFocusTraversalKeys(
            KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
    
        setPreferredSize(new Dimension(200, 200));
    
        String aString = "aStr";
        getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), aString);
        getActionMap().put(aString, new AbstractAction() {
          @Override public void actionPerformed(ActionEvent e) {
            System.out.println("a is typed");
          }
        });
        String tabString = "TAB";
        getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
          KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), tabString);
        getActionMap().put(tabString, new AbstractAction() {
          @Override public void actionPerformed(ActionEvent e) {
            System.out.println("tab is typed");
          }
        });
      }
    }
    

提交回复
热议问题