0

jf は、200 ミリ秒ごとにピクセルを移動しようとしている JFrame です。このメソッドを作成したので、続行する前にソフトウェアを 200 ミリ秒一時停止します。millis と millisn は static long です。

public static void waitsec() {

        millis =System.currentTimeMillis();
        millisn =System.currentTimeMillis();
            while (millisn<(millis+200)){
                millisn=System.currentTimeMillis();
            }
                }

次の部分は、ボタンが押されたときに JPanel (jp) をゆっくりと 50 ピクセル移動させようとしている部分です。

public void actionPerformed(ActionEvent h){
if (h.getSource() == button){
    for (int i = 0; i <50; ++i){
        waitsec();
        out.println ("" + i);//I'm checkinf if the waitsec() is working OK
        x +=1;
        jp.setLocation(x, 0);
        totalGUI.repaint();
        jp.setVisible(true);//setting visible so I could focus on it
        jp.requestFocusInWindow (); //suspicious part
        jp.requestFocus ();  
}}
}

このプログラムを実行した結果: 数字が表示されなくなると、JPanel は完全には動きません (プログラムの実行が終了します)。ウィンドウを最小化および最大化しようとすると、プログラムがまったくフォーカスされていないかのように、プログラムの実行が完了するまで表示されません...可視に設定してフォーカスしたのに、フォーカスしないのはなぜですか?

4

1 に答える 1

2

いろいろ...

まず、イベント ディスパッチ スレッドをブロックして、再描画イベントを含む新しいイベントを処理できないようにします。これにより、アプリケーションがハングしたように見えます。

次に、メソッドをローリングする代わりにwaitSec、使用可能な API 機能を利用する必要があります。たとえば、CPU サイクルを消費する期間が経過するまでループするのではなく、代わりに使用する必要がありますThread.sleep

そうは言っても、EDT のコンテキスト内で決して寝てはいけません。

代わりにjavax.swing.Timer、定期的にイベントを発生させるように構成できる のようなものを使用する必要があります。これの利点は、EDT のコンテキスト内でイベントを発生させ、内部から UI を安全に更新できることです (たとえば、独自のスレッドを作成する場合とは異なります)。

詳細については、Swingでの同時実行とSwingタイマーの使用方法をご覧ください。

第三に、JPanelデフォルトではフォーカス可能ではないため、呼び出しrequestFocusInWindowが影響を与える可能性は低い

第 4 に、Swing はデフォルトでレイアウト マネージャーを使用するため、実際にはこれにも苦労している可能性があります。

于 2013-10-27T22:45:11.560 に答える