1

次のコード行では、Button1が押されると、encode()メソッドの実行が完了するまでJframeが応答しなくなります。しかし、進行状況を表示するJframeの進行状況バーを更新する必要があります。

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {                                   
    try {
        if (flagState == 0) {
            WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode());
        } else if (flagState == 1) {
            WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode());            
        }
    } catch (WavFileException | IOException e) {
        notes.setText(e.getMessage());
    }
}         

私はこれをやろうと思った

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {                                   
    try {
        if (flagState == 0) {
            Thread t = new Thread(new Runnable() {
                               public void run() {
                                  WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode()); 
                               }
                            };)
            t.start();
        } else if (flagState == 1) {
            Thread t = new Thread(new Runnable() {
                               public void run() {
                                  WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode()); 
                               }
                            };)
            t.start();
        }
    } catch (WavFileException | IOException e) {
        notes.setText(e.getMessage());
    }
} 

encode()メソッドからプログレスバーを更新します。

しかし、私はそれがモジュール間の強い結合になることを理解しています、そして私はそれを望んでいません。

また、毎回新しいスレッドを呼び出すことは良い考えではないと思います(ExecutorServiceについて考えましたが、使用方法がわかりません)。

これをまともなピースコードにするにはどうすればよいですか?

4

3 に答える 3

1

スレッド化は間違いなくここで紹介する必要があるものです。完了するまでにかなりの時間がかかるものは、awtイベントスレッドで実行しないでください。

ボタンがクリックされるたびに新しいスレッドを生成することは、本質的に問題ではありません。ただし、最初のスレッドが完了する前に、同じことを実行する多くのスレッドを生成できる可能性があることを考慮する必要があります。必要に応じてエグゼキュータを使用できますが、おそらく必要ありません。

進行状況の追跡については、定期的に他のスレッドにクエリを実行し、必要に応じて進行状況バーを更新する別のスレッドを追加します。これが私がそれを構築する方法です:

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {
    disableButton1();
    final Thread t;
    if (flagState == 0) {
        t = new Thread(new Runnable() {
            public void run() {
                try {
                    WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode());
                } catch (WavFileException | IOException e) {
                    notes.setText(e.getMessage());
                }
            }
        });
    } else if (flagState == 1) {
        t = new Thread(new Runnable() {
            public void run() {
                try {
                    WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode()); 
                } catch (WavFileException | IOException e) {
                    notes.setText(e.getMessage());
                }
            }
        });
    }

    Thread monitor = new Thread(new Runnable() {
        public void run() {
            try {
                while (notComplete(t)) {
                    setProgressBar(getProgress(t));
                    Thread.sleep(SLEEP_TIME);
                }
                t.join();
            } finally {
                enableButton1();
            }
        }
    });

    t.start();
    monitor.start();
}
于 2012-09-10T18:25:09.110 に答える
1

n Button1が押されると、次のコード行は、encode()メソッドの実行が完了するまでJframeが応答しなくなります。しかし、進行状況を表示するJframeの進行状況バーを更新する必要があります。

Swingの同時実行性に問題があり、EDTをブロックし、コードが終了するまでGUIが応答しなくなりました

于 2012-09-10T18:20:18.143 に答える
0

マルチスレッドはあなたが必要とするものです、私が考えることができる他の良い方法はありません新しいスレッドを呼び出すことを心配しないでください、それは彼らがそこにあるものです、jvmはすぐに使えるスレッドプールを持っています、この種のものは本当にうまくいきますスレッド、試してみてください!

Runnableを拡張するクラスを作成するか、runメソッドを実装するか、現在のメソッドを呼び出すようにします。これで十分です。

また、短時間スリープさせて、スリープ時間が終了するたびにステータスを確認することもできます。プロセスが終了した場合は、続行できます。そうでない場合は、別の短時間スリープに戻ることができます。そうする必要はありません。何度も聞いてください。

お役に立てば幸いです。

于 2012-09-10T18:16:47.707 に答える