- ベストアンサー
無限ループをわざと作って時計をつくりたい
無限ループをわざと作って時計を作ろうと思っています。 while(true){ 処理 } とすると無限ループを作ることができると書いてありましたので private void btnRedActionPerformed(java.awt.event.ActionEvent evt) { while(true) { taOutput.setText(""); Date d = new Date(); taOutput.append(d +":" ); Color c = new Color(102,255,255); taOutput.setBackground(c); Font f = new Font(Font.SERIF, Font.ITALIC, 25); taOutput.setFont(f); } } として実行してボタンを押すと処理が止まって固まってしまうのです。 出力画面にOutOfMemoryErrorと書いてあるのでそのへんの理由だと思うのですが。 ちなみに for (int i = 0; i<5; i++) { } でテストするとうまく動きます。 これを固まらせずにうまく無限ループを続けさせるにはどうしたらいいのでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
無限ループを使用することについては意見が分かれるところかと思いますが、私は、ちゃんとThread.sleep(n)を呼び出してやれば、それほどCPUにも負担をかけないと思っています。まあ、javax.swing.Timerを使う方がスマートではありますが。 でも、メインスレッドの中で、無限ループを使うのは、やはり絶対に駄目です。理由はrinkunさんのおっしゃる通りです。 メインスレッドは一仕事終えて落ち着くまで、描画をしてくれないのです。 以下にThreadと無限ループを使った場合の例を挙げておきます。 import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class WhileTest extends JFrame implements ActionListener { JButton btn; JTextArea taOutput; public static void main(String[] args){ WhileTest f=new WhileTest(); f.setSize(400, 300); f.setVisible(true); } public WhileTest(){ Container cp=getContentPane(); cp.setLayout(new BorderLayout()); btn=new JButton("start"); btn.addActionListener(this); taOutput=new JTextArea(); cp.add(btn, BorderLayout.NORTH); cp.add(new JScrollPane(taOutput), BorderLayout.CENTER); } public void actionPerformed(ActionEvent evt) { TimerThread t=new TimerThread(); t.start(); } class TimerThread extends Thread{ public void run(){ while(true){ Date d = new Date(); taOutput.setText(d +":" ); try{ Thread.sleep(100); }catch(InterruptedException ex){ } } } } }
その他の回答 (3)
- _ranco_
- ベストアンサー率58% (126/214)
> ちゃんとThread.sleep(n)を呼び出してやれば Thread.sleep()は、スレッドのスケジューリングを放棄しないから、厳しい条件ではだめですよ。javax.swing.Timerのソースコードを見ると、良い勉強になります。また、別スレッドからGUIのコードを呼ぶときは、やはり厳しい条件のときにはinvokeLater()やinvokeAndWait()をかませる必要があります。初心者も、そのことは知っておくべきです。
- _ranco_
- ベストアンサー率58% (126/214)
javax.swig.Timerを使ってください。無限ループは、CPUのサイクルを浪費する極悪人です。ゼッタイに使ってはいけません。rinkun氏案の別スレッドも、無限ループの中で生成するのならノーグッド!です。
- rinkun
- ベストアンサー率44% (706/1571)
画面の表示はどこで更新しているのかな? 通常、GUIフレームワークでの画面の更新などはコールバック・メソッド(btnRedActionPerformedなど)を抜けた後でフレームワークから画面更新メソッドを呼び出して行っています。 ところがコールバック・メソッドの中で無限ループしてしまうとコールバック・メソッドは終了せず、画面の更新などは一切されなくなってしまいます。 実際のところフレームワークは画面の更新だけでなく、イベント処理なども行っていますので、無限ループするならループの中で一連の処理を行わなければいけません。VBではイベント処理を呼び出すDoEventsがありますが、Javaでは知りません。基本的にはコールバック・メソッドの中では無限ループをしないことです。 どうしても無限ループ処理をしたい場合は、別スレッドを起動して行いましょう。そうすればコールバック・メソッドはスレッドを立ち上げてすぐに終わりますのでイベント処理には問題ありません。