【问题标题】:How to add KeyListener to JComponent when mouse is entered?输入鼠标时如何将KeyListener添加到JComponent?
【发布时间】:2013-08-14 14:28:50
【问题描述】:

我创建了扩展JComponent 的自定义按钮类,并希望在mouseEntered 事件上添加KeyListener(然后在mouseExited 上删除)。所以我的目标是 - 当鼠标进入这个JComponent - 然后如果我按 Enter - 一些代码将被执行,仅与这个按钮相关。我该怎么做?

【问题讨论】:

  • 你试过了吗?
  • @ErnestasGruodis :不要使用 KeyListeners,使用 Key Bindings。从 Swing 的角度来看,KeyListeners 是低级的:-)
  • 为什么不使用一个布尔值来根据鼠标位置控制特定键事件的执行?

标签: java swing keylistener jcomponent


【解决方案1】:

使用Key Bindings 而不是KeyListeners,因为后者对于Swing 来说是低级的。只需将鼠标移到JButton 上,然后按ENTER,然后将鼠标移到JButton 的范围之外并再次尝试按ENTER。看看这个例子,看看这是否是你想要的:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonBinding {

    private JPanel contentPane;
    private JTextField tField;
    private JButton button;
    private KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");

    private Action action = new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            System.out.println("Action Performed");
            contentPane.setBackground(Color.BLUE);
        }
    };

    private MouseAdapter mouseActions = new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent me) {
            System.out.println("Mouse Entered");
            JButton button = (JButton) me.getSource(); 
            button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "enter");
            button.getActionMap().put("enter", action);
        }

        @Override
        public void mouseExited(MouseEvent me) {
            System.out.println("Mouse Exited");
            JButton button = (JButton) me.getSource();
            button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "none");
            contentPane.setBackground(Color.RED);
        }
    };  

    private void displayGUI() {
        JFrame frame = new JFrame("Button Binding Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        contentPane = new JPanel();
        contentPane.setOpaque(true);
        tField = new JTextField(10);
        button = new JButton("Click Me");
        button.addMouseListener(mouseActions);

        contentPane.add(tField);
        contentPane.add(button);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new ButtonBinding().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

【讨论】:

  • +1 是使用 keyBindings 的好例子。吹毛求疵:a) 动作有一个 enabled 属性,所以不需要添加/删除绑定 b) mouseEvent 携带它的源,所以不需要访问外部字段 c) JPanel 默认是不透明的
  • @kleopatra :Thankyou and KEEP SMILING :-) 虽然我在 Java 教程中读到,JPanel 默认情况下是不透明的,尽管并非对所有LookAndFeels 都适用,这就是为什么我总是使用调用此属性的原因在JPanel 上设置背景:-) 如Java Tutorials 所示。虽然 OP 说,他/她想在Mouse Exit 删除它,因此我做了那件事:(
  • 关于不透明性的好点,往往会忘记 LAF 可能会做出其他决定:-) 至于 OP 的要求:通常没有完全指定,这里我认为重要的部分是触发动作应该是 仅当鼠标悬停在组件上时才可能 - 但这是猜测。
  • 解决方案完美运行 :) 刚刚更改 getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, null); 确实谢谢!
猜你喜欢
  • 2021-12-20
  • 2022-12-07
  • 2017-04-19
  • 2021-01-09
  • 1970-01-01
  • 2013-12-24
  • 2012-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多