2016-03-22 19 views
0

スレッドが実行を停止するまで実行を継続するwhileループを設定するのは良い方法ではありませんが、他のアイディアを使い果たしてしまいました。しかし、私がこれに似たもの(あるいはこれに似たもの)を使用しても、私のプログラムを正しく実行することができません。ここでスレッドを使用しているときにwhileループを終了できない

は私のコードは次のとおりです。示すように、そのポイントの作品に、プログラムをコメントアウトwhileループ(条件におけるOkToShowAlternativesと1)とdisplayAlternatives()メソッドの呼び出しで

public void phase1() { 
    phase1CompoundLabels = new JLabel[numberOfElements]; 
    okToShowAlternatives = false; 

    remove(btnNewButton); 
    revalidate(); 
    repaint(); 

    while (totalNoOfPhase1Trials > 399) { 
     Phase1Trial phase1Trial = new Phase1Trial(numberOfElements, elementColors); 

     // this displays a set of images 
     displayComplexStimulus(phase1Trial.getComplexStimulus()); 

     validate(); 

     // after calling this method the images get removed after two 
     // seconds and the okToShowAlternatives variable gets its value 
     // changed to true 
     removeElementsAfterInterval(2000, phase1CompoundLabels); 

     // while(okToShowAlternatives == false){ 
     // } 

     // calling this method displays two images 
     // displayAlternatives(phase1Trial.getcorrectImage(), 
     // phase1Trial.getincorrectImage(), 
     // phase1Trial.getcorrectElementIsOnLeft()); 


private void removeElementsAfterInterval(int milliseconds, JLabel[] labels) { 
    Thread compoundThread = new Thread(new Runnable() { 

     public void run() { 
      try { 
       Thread.currentThread().sleep(milliseconds); 
       for (int i = 0; i < labels.length; i++) { 
        remove(labels[i]); 
        revalidate(); 
        repaint(); 

       } 
       okToShowAlternatives = true; 
       System.out.println("OkToShowAlternatives: " + okToShowAlternatives); 

      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       Thread.currentThread().interrupt(); 
      } 

     } 

    }); 
    compoundThread.start(); 
} 

画像のセットが2秒間表示された後、jpanelから削除されます。しかし、whileループをインクルードすると、画像の表示が止まり、jframeを閉じることさえできません。完全に反応しません。

ただし、OkToShowElements変数の値がtrueに変更されたかどうかを確認するためにprint文をインクルードしたときは、それが実行されます。だから、whileループの条件はもはや満たされるべきではないので、whileループから抜け出してコードの次の部分に進むべきですか?

答えて

0

あなたは別のスレッドからSwingコンポーネントと対話することはできません。 Swingは単一スレッドで設計されているため、UIスレッドとは別のスレッドからSwingのコンポーネントツリーとのやりとりを行うと、あらゆる種類の競合状態やメモリの可視性の問題が発生する可能性があります。

利用スイングタイマーは、指定された遅延の後、SwingのUIスレッド上でコードを実行するには:Oracleのウェブサイト上How To Use Swing TimersのJavaチュートリアルを参照して、さらに参考のために

ActionListener executeThisAfterDelay = ...; 
Timer timer = new Timer(speed, executeThisAfterDelay); 
timer.setInitialDelay(pause); 
timer.start(); 

+0

jpanelのコンポーネントを変更している場合、すべてが同じスレッドになければならないと言っていますか?私は混乱しています。なぜなら、あなたはGUIを使うときにマルチスレッドを使うことは決してできないからです。 – lb91

+1

Erwinが言ったことは、別のスレッドでスイングコンポーネントとやりとりしないということです。他の多くのことをするためにスレッドを利用することはできますが、guiコンポーネントと直接対話しないでください。 –

+0

@ lb91 Adrianは正しいです。複数のスレッドを使用できますが、Swingと直接対話することはできません。しかし、別のメソッド 'EventQueue.invokeLater'を使用して、あとでUIスレッド上で実行するコードをスケジュールすることができます。必要に応じて、別のスレッドがUIスレッドで何かを行うために 'EventQueue.invokeAndWait'を行うこともできますが、最良のマルチスレッドパフォーマンスを得るためには後者の方法を避けてください。 –

関連する問題