java - 如何通过文本 Pane 隐藏 Swing 加速器?

标签 java swing focus keyboard-shortcuts

我有一个带有多个 Pane 的 Swing 应用程序。有些 Pane 是文本 Pane (JTextPane),有些是类似对话框的(带有按钮和 slider ),有些是图形的(自定义绘制)。我在主菜单中使用简单的加速器定义了一些操作,例如 KPO

我希望仅当当前聚焦的 Pane 未处理这些加速器时,菜单操作才会处理它们。具体来说,当用户只是在文本 Pane 中键入内容时,我不希望菜单处理它们。

我正在使用以下方法创建操作和菜单项:

action = new javax.swing.AbstractAction
new MenuItem(action)

我正在注册加速器:

action.putValue(javax.swing.Action.ACCELERATOR_KEY, keyStroke)

是否可以“吃掉”(抑制)在文本 Pane 中处理的按键的按键事件,以便它们不会传递到主菜单进行全局处理?

如果没有,是否有一些替代方法可以执行类似的操作,例如注册我知道仅在某些 Pane 的文本 Pane 中不应处理的加速器?

我将根据答案添加代码,以使问题更清晰(并使开发替代解决方案更容易):

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

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;

public class TestMenuBindings {

    public static void main(String[] args) {
        JMenuBar menuBar = new JMenuBar();
        final JMenu menu = new JMenu("Print");
        final Action oAction = new PrintAction("O",KeyStroke.getKeyStroke(KeyEvent.VK_O, 0));
        menu.add(oAction);
        menuBar.add(menu);
        JFrame frm = new JFrame("Frame");
        frm.setJMenuBar(menuBar);
        JTextArea area = new JTextArea("Here I want no accelerators", 10, 40);
        frm.add(new JScrollPane(area));
        frm.add(new JTextField("Here I want accelerators working"), BorderLayout.SOUTH);
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.pack();
        frm.setVisible(true);
    }

    private static class PrintAction extends AbstractAction {
        private String str;
        public PrintAction(String aPrintStr, KeyStroke aMnemonic) {
            super("Print: " + aPrintStr);
            str = aPrintStr;
            putValue(Action.ACCELERATOR_KEY, aMnemonic);
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(str);
        }
    }
}

最佳答案

这是一个例子。在文本区域中没有键绑定(bind)工作。在文本字段中使用所有键绑定(bind)。此外,所有菜单项都可以从菜单访问(启用)。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;

public class TestMenuBindings {

    public static void main(String[] args) {
        JMenuBar menuBar = new JMenuBar();
        final JMenu menu = new JMenu("Print");
        menu.add(new PrintAction("O", KeyStroke.getKeyStroke(KeyEvent.VK_O, 0)));
        menu.add(new PrintAction("K", KeyStroke.getKeyStroke(KeyEvent.VK_K, 0)));
        menu.add(new PrintAction("P", KeyStroke.getKeyStroke(KeyEvent.VK_P, 0)));
        menuBar.add(menu);
        JFrame frm = new JFrame("Frame");
        frm.setJMenuBar(menuBar);
        JTextArea area = new JTextArea("Here working no accelerators", 10, 40);
        area.addFocusListener(new FocusListener() {

            @Override
            public void focusLost(FocusEvent e) {
                setItemStatus(menu, true);
            }

            @Override
            public void focusGained(FocusEvent e) {
                setItemStatus(menu, false);
            }
        });
        frm.add(new JScrollPane(area));
        frm.add(new JTextField("Here working accelerators"), BorderLayout.SOUTH);
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.pack();
        frm.setVisible(true);
    }

    private static void setItemStatus(JMenu aMenu, boolean aStatus) {
        for (Component item : aMenu.getMenuComponents()) {
            ((JMenuItem) item).getAction().setEnabled(aStatus);
        }
    }
    private static class PrintAction extends AbstractAction {
        private String str;
        public PrintAction(String aPrintStr, KeyStroke aMnemonic) {
            super("Print: " + aPrintStr);
            str = aPrintStr;
            putValue(Action.ACCELERATOR_KEY, aMnemonic);
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(str);
        }
    }
}

关于java - 如何通过文本 Pane 隐藏 Swing 加速器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29252237/

相关文章:

WPF:特定控件/ View / View 模型上的 LostFocus 事件

java - 使用 jackson-dataformat-xml 重写 ArrayList XML 序列化

Java如何: proper GUI coding?

java - 检查浏览器是否支持盲人或部分视力的人?

java - 如何删除 JPanel 内图像和文本之间的空白?

Java——错误找不到符号

flash - 有没有办法在浏览器中提供 Flash 焦点而不需要用户单击它?

c# - 如何在 xamarin 中获得焦点 VisualElement?

java - 创建具有退出应用程序功能的选项菜单

java - 您如何将时间段划分为相等的时间间隔并找到当前时间段?