2017-07-31 20 views
0

私のアプリケーション内でこの問題を解決する方法に関するヘルプ/ガイダンスを探しています。さまざまなWebサイトでいくつかのフォーラム投稿を読んだ後、私はなぜこれがうまくいかないのか考えていると思いますが、なぜ私のアプリケーションでこれが起こるのか、そしてソリューションを実装する方法が不明です。処理中にJava、KeyPressed()が検出されない

keyPressed()関数を介してキーボードからユーザーからの応答を受け取るまでアプリケーションが待機するのを探します。私はアプリケーションをいくつかの関数(ここでは示されていないもの)に分け、runTrialEvent()のwhileループで応答を待っています。しかし、runTrialEvent()関数を実行すると、応答は取得されません。私はこれがどこにあるのか知っていますが、理由を完全に理解していません。

私は、キーボードで 't'を押すことによって実行されるrunTrialEvent()という関数に次のコードを持っています。

runTrialEvent()

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を(使用して、ユーザからの入力を)持っています。このコードは次のとおりです。

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 "); 

} 
} 

私のドローは()単にウィンドウにテキストを書き込みますので、何も実行されていません。誰かが解決策を持っていれば素晴らしいだろう。なぜこのようなことが起こったのかについての説明は非常に高く評価されます。

ありがとうございます!

答えて

1

処理では、すべての機能を実行するために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()関数を使用して入力を処理し、関数はをチェックし、特定のStringと等しいテキストがビジー待機をチェックします。ユーザーがこんにちはを入力するまで、これはビジー状態になると思われるかもしれません。

この機能を実行すると、keyPressed()機能が正常に機能していることがわかります。その時点で、テキストがhelloに等しくなるのを待っていますが、今はkeyPressed()関数が決して起動しないため、これは起こりません。

(今からこのようなコードを投稿してみてください。このプログラムは、余分なコードなしとのArduino、または任意のライブラリを必要とせずに、あなたの問題を示していることに注目してください。)

をとにかく、は、我々はこの問題をどのように修正すればよいです?処理を処理する2番目のスレッドを作成することはできますが、これはおそらく目的のために過剰です。

代わりに、ビジー待機を完全に排除するためにコードをリファクタリングする必要があります。 1つのアプローチは、データを受信したかどうかを追跡する変数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

こんにちは、応答いただきありがとうございます、もう少し理解してください。明確にするために、コードのかなりの部分は含まれていません。私はserialEvent()と他の関数を受け取ってrunTrialEvent()に渡すことができますが、この関数の実行中にkeyPressed入力を検出できないので、Arduinoとの入力を完全に処理する他の関数を混乱させます。 ? – user3212628

+0

@ user3212628あなたが切断されたスニペットの代わりに小さい[mcve]を投稿すると、あなたはもっと良い運を得られるでしょう(しかし、**これはあなたの完全なスケッチではありません)。しかし、基本的な考え方は何であろうと同じです。ビジー待機と 'delay()'を呼び出すことで、他の関数が起動する機会はありません。 –

+0

こんにちは、固体の説明、形式の謝罪は、人々が理解するのを助けるためにできるだけ多くの情報を含めるだけでなく、あまりにも多くのことの否定的な影響があります。あなたが記述した解決策に関しては、私のアプリケーションでどうやってやっていくのか。私はタイマーがなくなる前にユーザーの応答を受け取る必要があります、なぜ私はwhileループを使用したかについての私の推論。私は別のスレッドを作成せずにそれについて行くだろうどのようなアイデア? – user3212628

関連する問題