为啥键/鼠标侦听器检测到鼠标按下而不是按键? (Java awt 窗口)

Posted

技术标签:

【中文标题】为啥键/鼠标侦听器检测到鼠标按下而不是按键? (Java awt 窗口)【英文标题】:Why does the Key/Mouse listener detect mouse presses but not key presses? (Java awt window)为什么键/鼠标侦听器检测到鼠标按下而不是按键? (Java awt 窗口) 【发布时间】:2020-12-01 10:26:00 【问题描述】:

所以,我的窗口检测到鼠标按下而不是按键。

这里有一些缩短的代码:

public class Frame 
    public static final int MAX_WIDTH = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    public static final int MAX_HEIGHT = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();

    private static final JWindow window = new JWindow();
    private static final DrawMain dm = new DrawMain();
    private static final GIH gih = new GIH();

    public static void init() 
        window.setSize(CVar.clientSizeX, CVar.clientSizeY);
        window.setLocationRelativeTo(null);
        window.setAutoRequestFocus(true);
        window.add(dm);
        window.addMouseListener(mh);
        window.addMouseWheelListener(mh);
        window.addMouseMotionListener(mh);
        window.setVisible(true);
    

    public static void update() 
            window.remove(dm);
            window.removeMouseListener(mh);
            window.removeMouseMotionListener(mh);
            window.removeMouseWheelListener(mh);
            window.setSize(MAX_WIDTH, MAX_HEIGHT);
            window.setLocationRelativeTo(null);
            window.add(dm);
            window.setAutoRequestFocus(true);
            window.setAlwaysOnTop(true);
            window.addMouseListener(gih);
            window.addMouseWheelListener(gih);
            window.addMouseMotionListener(gih);
            window.addKeyListener(gih);
            window.setVisible(true);
    


public class GIH implements KeyListener, MouseListener, MouseMotionListener, MouseWheelListener 
    @Override
    public void keyReleased(KeyEvent e) 
        System.out.println(e.getKeyChar());
    

    @Override
    public void mouseClicked(MouseEvent e) 
        switch (e.getButton()) 
            case MouseEvent.BUTTON1 -> 
                System.out.println("Mouse 1 clicked");
            
            case MouseEvent.BUTTON3 -> 
                System.out.println("Mouse 3 clicked");
            
        
    

无论出于何种原因,如果我单击,我会收到我的鼠标 1 单击消息,但如果我按下一个键,则既不是按键字符,也不是游戏通常在按键时给出的输出。相反,我将相应的字符写入 IntelliJ(我的 IDE)。我尝试了 window 和 dm.requestFocus() 和 window.setAutoRequestFocus(true) 的多种变体,但它们都不起作用。有谁知道为什么? (注意:dm 只是一个带有paintComponent 方法的类)

【问题讨论】:

您有什么理由不使用JFrame 和setUndecordated(true)? 部分地,我试过了,我得到了很多通过用窗口替换它来修复的错误。老实说,我不知道为什么它修复了这些错误,但以这种方式修复它们比单独修复每个错误更容易。 组件必须具有焦点才能接收 KeyEvent。 1)不要使用 JWindow(如 Gennadii 建议的那样),而是使用上面建议的 JFrame。 2) 不要使用 KeyListener。而是使用Key Bindings。即使组件没有关注您的活动框架,它也允许您处理 KeyStroke 并调用 Action。阅读 How to Use Key Bindings 上的 Swing 教程中的部分以获取更多信息。另请查看:Motion Using the Keyboard 感谢您的建议。我现在已经为游戏编程了 5 年(因为我 12 岁),因此当时对编程几乎一无所知。因为代码是废话,所以我和平地修改了它,我得到了这个鼠标,是的,但没有按键故障,因为我几天前修改了 GameInputHandler 类。通过将 Window 更改为 JFrame 解决了错误,并且我没有出现随机错误。我敢打赌他们在那里是因为代码首先是一团糟。 ^^ 【参考方案1】:

尝试将 window.addKeyListener(...) 添加到 init() 方法中。

【讨论】:

对于这个小例子,它可以工作。问题是,游戏分为客户端和游戏。如果我在调用更新之前添加键侦听器在客户端中按下键会导致大量异常,因为键交互方法中的所有代码都将指向 null。 . . 您的窗口是否有所有者框架?来自 javadoc:“要在 GUI 中使用 JWindow 组件,您应该知道 JWindow 组件的拥有框架必须可见,以便窗口中的任何组件都能获得焦点。默认情况下,如果您没有为一个 JWindow 组件,为其创建一个不可见的拥有框架。结果是 JWindow 组件中的组件可能无法获得焦点。”,如果您的窗口没有焦点,它如何接收事件? 不,它没有。我认为 JWindow 就像一个 JFrame,没有像装饰这样不必要的东西。在我更改框架类中的一些主要元素之前,我想知道它为什么会起作用,因为 cmets 暗示它一开始就不应该有。

以上是关于为啥键/鼠标侦听器检测到鼠标按下而不是按键? (Java awt 窗口)的主要内容,如果未能解决你的问题,请参考以下文章

鼠标键挂钩 - 键侦听器未触发

求高手解决:js如何判断鼠标左键是不是按下?

如何在Mac上使用鼠标键来控制指针?技巧来啦

汇编语言检测鼠标右键是不是被按下了

检测 OS X 上的任何按键,包括修改键

JavaFX:如何在屏幕上的任何位置检测鼠标/键事件?