如何在BorderLayout中的特定JPanel上专注于键盘处理

时间:2016-01-23 02:18:08

标签: java swing

关于获取Widget Focus以在我的Java Swing BorderLayout的Panels中启用键盘处理,我遇到了一些问题。我能够获得North Panel的Focus,然后我的键盘处理程序将会触发。但是,如果我尝试为我的布局请求南面板或中心面板的焦点,它根本不起作用。似乎能够获得焦点的唯一小组是北小组。有谁知道为什么?这是BorderLayout的设计吗?

现在,我尝试从各种Panel中尝试拾取Focus的原因是,由于某些原因将Focus设置为North Panel,似乎每隔一段时间键盘处理程序设置就会在某些情况下注册输入钥匙似乎根本就没有开火。几乎就好像他们不在那里一样。所以我想我只是在我的布局中使用另一个Panel作为键盘输入的焦点,看看会发生什么,现在看来这个选项也不起作用。

有人有任何想法吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

不是直接答案,但我无法在评论

中发布代码
  

有没有办法转储或显示所有已注册的密钥绑定以验证它们是否以某种方式未注册?

我使用类似......

的东西
import java.awt.EventQueue;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.KeyStroke;

public class KeyMappings {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
//              try {
//                  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
//              } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
//                  ex.printStackTrace();
//              }

                getKeyBindingsFor(new JTree());
            }
        });
    }

    public static void getKeyBindingsFor(JComponent comp) {
        System.out.println("...WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
        getKeyBindingsFor(comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT));
        System.out.println("...WHEN_FOCUSED");
        getKeyBindingsFor(comp.getInputMap(JComponent.WHEN_FOCUSED));
        System.out.println("...WHEN_IN_FOCUSED_WINDOW");
        getKeyBindingsFor(comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW));
    }

    public static void getKeyBindingsFor(InputMap map) {
        if (map != null) {
            KeyStroke[] keys = map.allKeys();
            if (keys != null) {
                for (KeyStroke key : keys) {
                    Object value = map.get(key);
                    System.out.println(value + " = " + key);
                }
            } else {
                System.out.println("[none]");
            }
        }
    }
}

测试不同组件和外观的各种绑定

答案 1 :(得分:-1)

如果您想从所有组件获取键盘输入,可以使用KeyboardFocusManager.addKeyEventDispatcher

KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
    public boolean dispatchKeyEvent(KeyEvent e) {
        if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_R&&e.getID()==KeyEvent.KEY_RELEASED){
            //Execute this code when Ctrl+R is released
            return true;
        }
        return false;
    }
});

如果它是focusable,那么north似乎会收到关键事件,因此您可以通过将所有其他事件设置为不可聚焦来强制特定面板获得焦点并接收关键事件。将JTextField或JButton(仅测试的组件)添加到北面板会破坏这一点。