【问题标题】:Key Pressed acting as Key TypedKey Pressed 充当 Key Typed
【发布时间】:2015-02-16 07:15:41
【问题描述】:

我在尝试实现KeyEventDispatcher 时遇到了一个小问题。按住键盘上的任何键都会导致QuestGUI 在真假之间切换。这意味着它检查是否每次执行都按下了键。我想要的是当我按下“A”时,它会触发我的KeyEventDispatcher 处理的事件。然后它应该等到按下下一个键。我的代码如下所示。

Test.java

package core;

import java.awt.KeyboardFocusManager;
import javax.swing.JFrame;

public class Test
{
    public Test (){
        JFrame frame = new JFrame ();        
        frame.setResizable (false);
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo (null);
        frame.pack ();
        frame.setSize (800, 600);        
        frame.setVisible (true);

        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new KeyManager());
    }

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

KeyManager.java

package core;

import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;

public class KeyManager implements KeyEventDispatcher {

    private boolean QuestGUI;

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getID() == KeyEvent.KEY_PRESSED) {
            QuestGUI = !QuestGUI;
            System.out.println("QuestGUI" + QuestGUI);
        }
        return false;
    }
}

可以通过添加boolean来检查Q是否被按下来解决,它只有在Q被释放后才会起作用。喜欢PRESSED_Q。然后我需要为每个键绑定和匹配它。然而,这感觉很笨拙。我预计KEY_PRESSED 会自动执行此操作。

【问题讨论】:

  • 查看 KeyListener 的文档,您需要 keyPressed.:docs.oracle.com/javase/7/docs/api/java/awt/event/… 如果它的行为符合您的建议,那么您自己回答了问题,使用布尔值跟踪行为。似乎您正在实现“切换”功能,您可以通过按下和释放来跟踪它。
  • 那么没有比那个笨重的更好的选择了吗?
  • 根据我的经验,没有。再说一次,我已经有 4 年没有做过低级 Swing/AWT 了。可能有更好的选择。我对这个问题的理解是,某些东西不断发出 KEY_PRESSED 事件。如果该事件是恒定的,您需要自己跟踪向下/向上。您可以考虑扩展类并创建更有意义的 API,或者简单地使用 if(e.KEY_PRESSED){down = true;} else if(e.KEY_RELEASED) {down = false;} 的跟踪方法,然后通过 down 进行跟踪
  • 您是否考虑过使用键绑定 APi 代替? How to Use Key Bindings
  • 按键事件将定期触发(基于操作系统),因此您的布尔值将在真到假之间不断翻转。您需要能够分别检测到PRESSRELEASE。您可以考虑使用某种Map,键入KeyEvent 的虚拟键码

标签: java swing keyboard


【解决方案1】:

就我个人而言,我更喜欢对这种事情使用键绑定,这只是我,但你可以创建两个Actions,一个用于按下,一个用于释放,它只需要一个“键”值来设置Map 中的某个值(即"Up")到true/false 取决于触发器,但那是我......

核心问题是,KEY_PRESSED 事件将根据操作系统定期重复。这意味着您的QuestGUI 值不断被翻转。您需要检测KEY_PRESSEDKEY_RELEASED 事件并采取适当的措施,例如...

public class KeyManager implements KeyEventDispatcher {

    private boolean QuestGUI;

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getID() == KeyEvent.KEY_PRESSED && !QuestGUI) {
            QuestGUI = true;
            System.out.println("QuestGUI" + QuestGUI);
        } else if (e.getID() == KeyEvent.KEY_RELEASED && QuestGUI) {
            QuestGUI = false;
            System.out.println("QuestGUI" + QuestGUI);
        }
        return false;
    }
}

您还可以使用KeyEvent#getKeyCode 值,将其放在ListMap 中以检测何时按下/释放某些键...

就我个人而言,我认为键绑定会更容易管理、扩展和配置,但我想这一切都归结为上下文。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多