【问题标题】:Java - Waiting for some type of key press to continueJava - 等待某种类型的按键继续
【发布时间】:2011-10-28 06:11:27
【问题描述】:

在 Java 中实现“按 x 继续”类型的东西的最佳方式是什么?

具体来说,我有一个扩展 JFrame 的自定义类和一个扩展 JPanel 的自定义类。我有一个 Main.java(它有我的 JFrame 类的一个实例),并且在用户按下空格键之前我不想继续:

Main.java:

...code...
frame.waitForSpace();
...more code which gets executed only after space is pressed...

那么,在我的框架类中,我应该如何实现:

MyFrame.java:

/* This method only finishes when the space bar is pressed */
public void waitForSpace() {

}

顺便说一句,我的 JFrame 上有 KeyListener,它在按下空格按钮时工作。但我不太确定如何将其融入我正在尝试做的事情中。

示例代码会很棒!

【问题讨论】:

    标签: java swing jframe jpanel keylistener


    【解决方案1】:

    当用户按下空格键时,将你想做的任何事情都放入该处理程序中。很可能您不想在每次按下空格键时都做(无论如何),但只是在某些时候;因此,事件处理程序应该取决于某个变量的值,并且运行 before 您希望用户按空格的代码应该将该变量设置为表示“执行”的值。处理程序应在运行后将变量设置回默认值。

    【讨论】:

      【解决方案2】:

      请记住,Swing GUI 是事件驱动的。所以不要等待任何东西。相反,给你的类一个状态字段,可能是布尔值,在按键时更改状态变量,可能使用键绑定,然后不允许某些行为,除非状态已更改(通过 if 语句)。

      【讨论】:

        【解决方案3】:

        在调用 await() 时使用 CountDownLatch,当前 main() 线程将等待,直到从另一个线程调用 countDown() 方法。

        KeyEventDispatcher 允许您在全局范围内添加击键侦听器。因此,每当按下某个键时,都会从 EDT(事件调度线程)调用 dispatchKeyEvent(),在那里您可以检查是否按下了“空格”并释放 main() 正在等待的倒计时锁存器。

        但是,如果调用 waitForSpace() 的线程是 EDT,那么您将强制 EDT 等待自身,从而导致死锁。据我所知,在 EDT 上等待并仍然收到关键事件是不可能的。

        只要 JFrame 有焦点,这将起作用:

        public void waitForSpace() {
            final CountDownLatch latch = new CountDownLatch(1);
            KeyEventDispatcher dispatcher = new KeyEventDispatcher() {
                // Anonymous class invoked from EDT
                public boolean dispatchKeyEvent(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_SPACE)
                        latch.countDown();
                    return false;
                }
            };
            KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
            latch.await();  // current thread waits here until countDown() is called
            KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
        }
        

        【讨论】:

        • 您介意详细说明一下吗?我以前从来没有做过这样的事情。这段代码会去哪里?
        • 如果键入空格键,这是否只注册一次?它似乎注册了不止一次。
        • 每次调用该方法时,都会向侦听器添加一个新的 KeyEventDispatcher,但按下空格后会被移除。
        • 但如果我持有空间,则会触发多个事件。我该如何做到这一点,以便它基于输入的空格,而不是按下的空格?
        • 具体来说,如果你在“latch.countDown”上面添加一个打印语句,然后你按空格,它会打印两次
        【解决方案4】:

        不要使用 KeyLIstener。

        使用键绑定。您已经获得了键绑定教程的链接。

        【讨论】:

          猜你喜欢
          • 2013-09-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-07
          • 1970-01-01
          • 2016-08-16
          • 1970-01-01
          相关资源
          最近更新 更多