java - 在 JTextField 中点击空格键触发父窗口的键绑定(bind)

标签 java swing key-bindings

我在 JFrame 的根 Pane 中注册了一个事件,该事件在按下空格键(打开另一个窗口)时使用react。我在该 JFrame 中也有一个 JTextField。当用户处于我的文本字段的编辑模式并按下空格键时,空格事件应仅由文本字段使用,而不应转发到 JFrame 的 Action 映射。

我该怎么做?

这是该问题的可运行演示:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

public class TestDialog {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaceAction");
        frame.getRootPane().getActionMap().put("spaceAction", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("spaceAction");
            }
        });
        JTextField tf = new JTextField("textfield");
        JLabel label = new JLabel("otherComponent");
        label.setFocusable(true);
        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(tf);
        frame.getContentPane().add(label);
        frame.pack();
        frame.setVisible(true);

    }

}

最佳答案

使用空格键作为全局触发器不是一个好主意。但如果你真的需要它,这里是方法:

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.text.JTextComponent;

public class DialogTest {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaceAction");
        frame.getRootPane().getActionMap().put("spaceAction", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (EventQueue.getCurrentEvent() instanceof KeyEvent) {
                    KeyEvent ke = (KeyEvent) EventQueue.getCurrentEvent();
                    if (!(ke.getComponent() instanceof JTextComponent)) {
                        System.out.println("spaceAction");
                    } else {
                        System.out.println("Ignore event in text component");
                    }
                } else {
                    System.out.println("spaceAction");
                }
            }
        });
        JTextField tf = new JTextField("textfield");
        JLabel label = new JLabel("otherComponent");
        label.setFocusable(true);
        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(tf);
        frame.getContentPane().add(label);
        frame.pack();
        frame.setVisible(true);

    }

}

更好的方法是从根 Pane 开始遍历组件树,只为您需要的组件(例如所有标签)添加键绑定(bind)。这是我的遍历方法

/**
 * Searches for all children of the given component which are instances of the given class.
 *
 * @param aRoot start object for search.
 * @param aClass class to search.
 * @param <E> class of component.
 * @return list of all children of the given component which are instances of the given class. Never null.
 */
public static <E> List<E> getAllChildrenOfClass(Container aRoot, Class<E> aClass) {
    final List<E> result = new ArrayList<E>();
    final Component[] children = aRoot.getComponents();
    for (final Component c : children) {
        if (aClass.isInstance(c)) {
            result.add(aClass.cast(c));
        }
        if (c instanceof Container) {
            result.addAll(getAllChildrenOfClass((Container) c, aClass));
        }
    }
    return result;
}

关于java - 在 JTextField 中点击空格键触发父窗口的键绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36617194/

相关文章:

java代码读取文件夹中的所有.xml文件以及特定标签之间的值

java - 如何设置JPanel的透明背景?

java - 如何在关闭 Hook 中使用 swing?

java - 为什么在为 JPanel 使用键绑定(bind)时无法获取 KeyEvent.VK_TAB

java - 如何在 JAVA 中验证多行 JSON 负载

java - MOXy 的解码不一致

python - 键绑定(bind) 1-5 不工作 Tkinter

vim - 有没有办法查看所有 VIM 键绑定(bind)?

java - API 需要 2 分钟加载数据。想要使用缓存

java - java中的paint()没有显示