当前位置: 首页 > 面试题库 >

当我对JPanel使用键绑定时,为什么无法获得KeyEvent.VK_TAB

乔俊才
2023-03-14
问题内容

如果用户将焦点放在当前窗口上并按一个键,我将打印相关信息。但是,它适用于某些键,例如“ a”,但不适用于“ tab”。这是一个简单的演示:

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");
                }
            });     
        }   
    }
}

我该怎么做才能达到目标?提前致谢。


问题答案:

引自《如何使用Focus子系统》(Java™教程>使用JFC /
Swing创建GUI>使用其他Swing功能)
(由@
alex2410建议(链接到@camickr帖子)和@mKorbel建议):

在大多数外观模型中,使用Tab和Shift-Tab键浏览组件。这些键是默认的焦点遍历键,可以通过编程更改。

选项卡将焦点向前移动。Shift-
Tab键可将焦点向后移动。Tab键将焦点通过按钮移动到文本区域。附加的制表符会将光标移动到文本区域内,但不能移出文本区域,因为在文本区域内,Tab不是焦点遍历键。但是,Control-
Tab键可将焦点移出文本区域并移至第一个文本字段。同样,Control-Shift-Tab键可将焦点移出文本区域并移至上一个组件。

按惯例,Control键用于将焦点移出以特殊方式处理Tab的任何组件,例如JTable。
您刚刚收到了有关焦点体系结构的简短介绍。如果您需要更多详细信息,请参阅Focus
Subsystem的规范。

因此,如果要使Tab键绑定动作在面板中起作用,则需要从面板中删除Tab键焦点导航。

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");
      }
    });
  }
}


 类似资料:
  • 我收到的错误: 这是我的代码 我尝试了几种不同的方法来读取此文件,但我无法弄清楚为什么会发生这种情况。我使用的扩展名.rtf,.txt,认为这可能是文件本身的问题。该文件仅包含以下内容:

  • 为什么我总是得到这个错误? 表格: 要创建的链接

  • 问题内容: 之间有什么区别: 和 我知道JPanel是GUI组件的容器,但我确实看不到使用它的实用程序。当然,我错了,但我是从Swing开始的,所以…为什么我应该使用JPanel?真正的目的是什么? 问题答案: 为什么我应该使用JPanel? 您可以使用JPanel获得以下一项或多项好处: 将组件分组在一起。 为了更好地组织您的组件。 为了使我们能够使用 多种布局 并组合其效果。(例如,用于数字键

  • 将W,S和I,k绑定到乒乓球的左右桨。根据Eclipse,代码进入类p1_upaction扩展AbstractAction,但不运行公共void actionPerform(ActionEvent e)。我不知道该怎么办。键输入称为操作未注册。

  • 问题内容: 我做了一个将我的JFrame设置为全屏的JButton: 这是JFrame: 为什么当我运行游戏并全屏选择JButton时,JPanel渲染不正确? 我的意思是说,在我的黑色背景上有一个很大的灰色JPanel,没有JButton呈现。 问题答案: 问题是您正在创建多个不同的实例,但您完全不知道屏幕上实际可见哪个实例。 ,创建实例和调用,它创建的实例,以及......别急,我们,为什么我

  • 问题内容: 我想从文件中读取数据,但是在调用method 时得到了。即使我正在使用该方法,但它不起作用。 txt文件的第一行是: 问题答案: 怪罪法国语言环境:它使用逗号作为小数点分隔符,因此无法解析。 替换为可修复问题(演示1)。如果您想解析,请使用代替(demo 2 )。 您的代码中的第二个问题是使用用作分隔符。您应该使用单个反斜杠,否则包含的单词将破坏您的解析逻辑。