【问题标题】:JTextField and F10 key - how to remove key binding?JTextField 和 F10 键 - 如何删除键绑定?
【发布时间】:2013-09-05 22:23:50
【问题描述】:

我正在尝试从 JTextField 中删除 F10 按钮键绑定,但下面没有任何工作:

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.KEY_PRESSED), "none");
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.KEY_TYPED), "none");
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.KEY_RELEASED), "none");

实际上,我想控制弹出菜单 - 显示/隐藏,但 F10 无法正常工作 - 它正在执行一些其他操作。例如,如果我切换到 F11,一切正常。

据我所知 - Shift + F10 在各种平台上显示弹出窗口。

【问题讨论】:

  • 但 F10 无法正常工作 究竟是什么意思 - 它按预期显示弹出窗口(至少在 win 中,不知道其他操作系统),那么你期望做什么
  • 我的弹出窗口是简单的 JWindow,如果使用 F10 - 非常奇怪的行为 - 弹出按钮有时不接收 MouseEvents(它们应该淡入/淡出)。还有一件事 - 当我在鼠标悬停在 JTextField 上时按 F10 时 - 字段丢失并再次获得焦点。
  • 您是否尝试过其他一些条件,例如getInputMap(JComponent.WHEN_FOCUSED)
  • hmm,为什么要显示“假”弹出窗口(手动编码窗口)与默认(最佳:组件)popupMenu?无论如何,听起来您的自定义代码可能有问题 - 请显示一个演示问题的 SSCCE。

标签: java swing keystroke


【解决方案1】:

KeyStroke.getKeyStroke(int, int) 不用于获取新闻或发布事件的KeyStroke,它用于以KeyEvent.SHIFT_DOWN_MASK 和/或KeyEvent.CTRL_DOWN_MASK 和/的形式将修饰符应用于KeyStrokeKeyEvent.ALT_DOWN_MASK 和/或KeyEvent.ALT_GRAPH_DOWN_MASK 和/或KeyEvent.META_DOWN_MASK...

您应该使用getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0), "none"); 而不是getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.KEY_PRESSED), "none");

当我使用以下内容时,我可以获得在字段获得焦点时触发的关键动作......

import java.awt.BorderLayout;
import java.awt.EventQueue;
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.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestTextFieldKeyStroke {

    public static void main(String[] args) {
        new TestTextFieldKeyStroke();
    }

    public TestTextFieldKeyStroke() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JTextField field = new JTextField(20);
            add(field);
            JPopupMenu pop = new JPopupMenu();

            field.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0), "happy");
            field.getActionMap().put("happy", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Happy");
                }
            });

        }
    }
}

使用弹出窗口更新

根据前面的示例,如果我执行类似...

final JTextField field = new JTextField(20);
add(field);
JPopupMenu pop = new JPopupMenu();
pop.add(new JLabel("Hello"));
field.setComponentPopupMenu(pop);

field.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0), "happy");
field.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.CTRL_DOWN_MASK), "happy");
field.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.ALT_DOWN_MASK), "happy");
field.getActionMap().put("happy", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        JPopupMenu popup = field.getComponentPopupMenu();
        popup.show(field, 0, field.getHeight());
    }
});

我可以让它显示JPopupMenu

【讨论】:

  • 但是如何删除 F10、SHIFT+F10 和 CTRL+F10 的现有操作?我已经描述了下面的问题。
  • F10 是无障碍 API 用来聚焦菜单栏的系统击键......显然......
  • 您是在全局范围内删除它还是仅针对该字段?如果我将击键分配给该字段,我可以毫无问题地显示一个弹出窗口。您还应该了解,许多用户会期望 F10 执行特定操作,这不仅限于 Java,而是整个操作系统......
  • 我想删除它只是为了字段。
  • 在系统的其他地方开始拾取击键,没有关联的Action,键绑定 API 不使用该事件,允许对其进行进一步处理。 F10 不是与文本字段关联的击键,因此,仅在 InputMap 中输入一个条目是不够的
【解决方案2】:

我已经尝试过了,它正在工作:

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0), "doNothing");
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK), "doNothing");
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.CTRL_DOWN_MASK), "doNothing");

        getActionMap().put("doNothing", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //Do nothing
            }
        });

现在 F10Shift + F10Ctrl + F10 事件是删除。但是如果我跳过getActionMap().put("doNothing", new AbstractAction() {}),那么上面的键绑定不起作用..,但似乎在某个地方仍然附加了一些操作 - 光标正在改变(从Cursor.TEXT_CURSORCursor.MOVE_CURSOR 并再次回到Cursor.TEXT_CURSOR)当我按下这些按钮(应该什么都不做)。我试过textField.getActionMap().size() 但它返回0。所以我想动作附加到其他一些组件。能查出来吗?

编辑:

在这里http://docs.oracle.com/javase/...我找到了所有答案... :)

【讨论】:

  • 这在没有上下文的情况下没有多大意义 - 你仍然没有解释为什么你想与框架作斗争......
  • 因为我正在使用我的弹出菜单(自定义构建,扩展JWindow),并且预定义的 F10 操作不允许它正常运行。我必须禁用所有 F10 事件。
  • 我必须禁用所有 F10 不,很可能您在未显示的代码中做错了
  • 我想我要指出何时我将创建自己的 TextField,就像我对 ComboBox 所做的那样,我现在可以完全控制,还有不同的 ScrollBar - 定制,所有扩展都只是 JComponents、JWindows、JPanels ..
  • @kleopatra 只需尝试将 JTextField 放在面板上,然后反复单击 F10 - 看看 Cursor 的行为。
猜你喜欢
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多