处理:Java、KeyPressed() 在运行函数时未检测到?

问题描述 投票:0回答:2

寻找有关如何在我的应用程序中解决此问题的一些帮助/指导。在阅读了各个网站上的几篇论坛帖子后,我想我知道为什么这不起作用,但我不确定为什么会在我的应用程序中发生这种情况以及如何实施解决方案。

寻找应用程序等待,直到通过 keyPressed() 函数通过键盘收到用户的响应。我已将应用程序分成几个函数(有些函数此处未显示),并在 runTrialEvent() 的 while 循环中等待响应。但是,一旦我运行 runTrialEvent() 函数,就永远不会收到响应。我知道这就是问题所在,但不完全理解原因。

我在名为 runTrialEvent() 的函数中有以下代码,该函数通过按键盘上的“t”来运行。

运行TrialEvent()

 void runTrialEvent(Serial myPort) 
 {
  
      //////////////////////////////////////////////
      //This While Loop is where the issues arise

      while (trialTimer.isFinished() == false && userResponded == false )
      {
        println("Awaiting User Response");
        
        delay (300);
      }

      //////////////////////////////////////////////////     
 
      if (userResponded == true)
      {
        //Debug Info
        println("User responded in time ");   
      }
      
      else if (trialTimer.isFinished() == true)
      {
         println("User failed to respond in time ");
      }
}

我使用 keyPressed() 来自用户的输入,该输入在循环正常之前工作。这段代码是:

按键()

 void keyPressed() 
 {
 if (key == 'f' || key == 'F' )
 {
   println("User Answered First");
   //allTrials[i].setUserAnswer("F");
   userResponded = true;
   println("User Response Recorded ");
   
 }
 
 else if (key == 's' || key == 'S')
 {
   println("User Answered Second");
   //allTrials[i].setUserAnswer("S");
   userResponded = true;
   println("User Response Recorded ");
   
 }
 }

我的draw()只是在窗口上写入文本,所以那里没有运行任何东西。如果有人有任何解决方案那就太好了。任何关于为什么会发生这种情况的解释将不胜感激。

谢谢!

java while-loop keyboard processing
2个回答
1
投票

处理使用单个线程来运行其所有功能。这意味着如果你让一个函数永远运行,其他函数将永远没有机会触发。

请尝试发布一个 MCVE,以尽可能少的行数显示您的问题,同时足够完整,以便我们复制和粘贴以自行运行。这是一个显示您的问题的示例程序:

String text = "";

void draw(){
  background(64);
  textAlign(CENTER, CENTER);
  text(text, width/2, height/2);
}

void keyPressed(){
  text += key;
}

void mousePressed(){

  while(!text.equals("hello")){
    println("Waiting for text to equal hello.");
    delay(1000);
  }

}

这个程序所做的事情与您想要做的事情非常相似。它使用

keyPressed()
函数来处理输入,然后
mousePressed()
函数检查 和 busy-waits 文本是否等于某个字符串。您可能希望这会忙等待,直到用户输入 hello。

如果运行此函数,您会注意到

keyPressed()
函数工作正常,直到您单击鼠标。此时,它一直在等待文本等于
hello
,但这永远不会发生,因为现在
keyPressed()
函数永远不会触发。

(注意这个程序如何在没有任何额外代码且不需要 Arduino 或任何库的情况下显示您的问题。从现在开始,请尝试发布这样的代码。)

无论如何,我们如何解决这个问题?您可以创建第二个线程来处理您的处理,但这对于您的目的来说可能有点过分了。

相反,您需要重构代码以完全消除忙等待。一种方法是使用

boolean
变量来跟踪您是否已收到数据。用它来检查是否需要做某事,然后在收到数据时进行设置。

这是我们的小示例程序中的方法:

String text = "";
boolean helloReceived = false;

void draw(){
  background(64);
  textAlign(CENTER, CENTER);
  text(text, width/2, height/2);
}

void keyPressed(){
  text += key;

  if(text.equals("hello")){
     helloReceived = true; 
  }
}

void mousePressed(){

  if(helloReceived){
    println("Text now equals hello!");
  }
}

现在代码使用

helloReceived
变量来跟踪是否满足条件。这有点做作,但我正在尝试创建一个与您想要做的类似的示例。

此代码只是一个示例,您的实际代码可能需要比单个

boolean
值稍微复杂一些。但一般答案是相同的:您不应该忙等待或使用
delay()
函数,因为它会阻止其他函数被触发。相反,重构您的代码以完全消除等待。


0
投票

while 循环和delay() 可能会冻结草图并使其无法注册按键。

将你的 fps 设置为 120 左右然后使用

if (framecount%2 == 0) {
  //draw stuff
}

keyPressed 的注册速度将快于屏幕的更新速度。 我想,您甚至可以将 fps 增加到 1000 左右,以最大限度地利用 CPU 资源,尽管开销会影响这种方法的效率。

© www.soinside.com 2019 - 2024. All rights reserved.