为什么我不能得到KeyEvent.VK_TAB当我使用密钥绑定为一个JPanel [英] Why can't I get KeyEvent.VK_TAB when I use Key Binding for a JPanel

查看:278
本文介绍了为什么我不能得到KeyEvent.VK_TAB当我使用密钥绑定为一个JPanel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将打印相关信息,如果用户集中在当前窗口和preSS的关键。但是,它的工作原理像'一'某些键而不是'标签'。下面是一个简单的演示:

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:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;


public class KeyBindingTest {
    public static void main(String[] args) {
        KeyBindingTest test = new KeyBindingTest();
        test.createUI();
    }

    public void createUI(){
        JFrame frame = new JFrame("KeyBinding Test");
        MainPanel mainPanel = new MainPanel();
        frame.add(mainPanel,BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @SuppressWarnings("serial")
    class MainPanel extends JPanel{
        public MainPanel(){
            setPreferredSize(new Dimension(200, 200));
            //========================key binding============================
            requestFocusInWindow();
            String aString = "aStr";
            getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), aString);
            getActionMap().put(aString, new AbstractAction() {          
                @Override
                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
                    System.out.println("a is typed");
                }
            });     

            String tabString = "tabStr";
            getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), tabString);
            getActionMap().put(tabString, new AbstractAction() {            
                @Override
                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
                    System.out.println("tab is typed");
                }
            });     
        }   
    }
}

我能做些什么去实现它?先谢谢了。

What can I do to reach it? Thanks in advance.

推荐答案

从引用的如何使用对焦子系统(在Java™教程>创建GUI随着JFC / Swing的>使用其他Swing功能)(由@ alex2410(链接建议@camickr后)和@mKorbel):

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):

在,大多数的外观模型,组件使用Tab导航和Shift-Tab键。这些键的默认焦点遍历键,并可以通过编程来改变。

  ...

  标签转移在向前方向上的焦点。 Shift-Tab键向后方向移动的焦点。 Tab键通过按键把焦点移动到文本区。附加Tab键移动文本区域内的光标,但没有脱离文本区域,因为一个文本区域内,标签不是一个焦点遍历键。但是,控制-Tab键将焦点移动出的文本区域,并成为第一个文本框。同样,控制-Shift-Tab键将焦点移动出的文本区域,进入previous组件。

  ...

  控制键用于按约定将焦点移出把标签以一种特殊的方式,如JTable的任何组件。

  你刚刚收到一个简要介绍了重点建筑。如果您想了解更多详细信息,请参阅的焦点子系统

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.

所以,如果你想跳键绑定行动工作小组,你需要从面板上的Tab键焦点导航。

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<KeyStroke> forwardKeys = new HashSet<KeyStroke>(1);
    forwardKeys.add(KeyStroke.getKeyStroke(
        KeyEvent.VK_TAB, InputEvent.CTRL_MASK));
    setFocusTraversalKeys(
        KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);

    Set<KeyStroke> backwardKeys = new HashSet<KeyStroke>(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");
      }
    });
  }
}

这篇关于为什么我不能得到KeyEvent.VK_TAB当我使用密钥绑定为一个JPanel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆