6

これは、そこにいるスイングの専門家のためのものです。私はこの問題にかなりの時間を費やしてきたので、問題を説明するのに数行かかります。

スタンドアロンのJavaSwingアプリケーション(Java 6)があります。私のアプリケーションでは、ラジオボタングループのあるフレームがあります。グループ内のすべてのボタンにリンクされた単一のアクションがあります。このアクションは、どのラジオボタンが選択されているかを確認し、いくつかの作業を実行します。「作業」には、バックグラウンドの計算と、アプリケーション内の他の2つのフレームでのペイントが含まれます。バックグラウンド計算はマルチスレッドです。

ユーザーがラジオボタンの1つを選択すると、プログレスバーを表示したいと思います。ただし、ラジオボタンが選択されている場合、ラジオボタンへのアクションが発生している間は、進行状況バーは表示されません。jdialogタイプのプログレスバーやガラス板などを試しましたが、「作業」がすべて完了するまで表示されません。これは、対応するアクションの「作業」が完了するまで、Swingがラジオボタンのペイントを終了しないためと思われます。また、EDTは一度に1つのことしか実行しないため、プログレスバーダイアログ(またはガラスペイン)が表示されることはありません。

次に、SwingWorkerを使用してこのすべての「作業」を実行しようとしました。SwingWorkerのdone()メソッドでプログレスバーを起動(またはガラスペインをアクティブ化)し、SwingWorkerを起動してプログレスバーを閉じます(またはガラスペインを非アクティブ化します)。これでプログレスバーは正常に表示されるようですが、「作業」の一部であるペイントが完了せず、ペイントのアーティファクトが残ることがあります(paintComponentメソッドはかなり複雑なので、ここで再現したくありません)。ウィンドウのサイズを変更すると、アーティファクトが消えます。実際、これは、SwingWorkerの代わりにThreadを拡張するクラスを使用した場合にも発生します。これはすべて、Swingがスレッドセーフではなく、EDT以外のスレッドからGUI作業を実行しようとしているためです。私はその部分を理解しています。

私は何をしますか?「作業」には約30秒かかりますが、プログラムが機能していることをユーザーに示すことなく、それを行うには長すぎるようです。また、カーソルを待機カーソルに変更しようとしましたが、上記と同じ問題が発生しました。私にできることは、フレームを無効にして、フレームのタイトルを「working...」のようなテキストに設定することだけです。

誰かが以前にこの問題を見ましたか?

4

2 に答える 2

4

作品をEDTからSwingWorkerに移動すると(これは正しいことでした)、作品と絵画の両方がSwingWorkerに移動したように聞こえます。ペイントはまだEDTで行われるはずです。これを実現するには、を使用SwingUtilities.invokeLaterしてバックグラウンドスレッドから再描画を呼び出すか、SwingWorker.publish(V ...)を使用します。これにより、ワーカースレッドから通知を受け取り、SwingWorker.process(を介してEDTで利用できるようになります。 V ...)テンプレートメソッド(オーバーライドします)。オーバーライドprocessは、画面の一部を再描画したり、進行状況を更新したり、必要に応じてその他の適切なアクションを実行したりすることで、中間通知を処理できます。ここで行われたUIの変更は、残りの作業が完了するのを待たずに表示されます。

于 2010-08-12T23:46:25.540 に答える
4

SwingWorkerスレッドで作業を行うのは正しいと思いますが、そこでペイントを行うべきではありません。

私は次のようになりがちです:

  • ActionListenerにプログレスバーを表示させ、swingworkerをオフにしてから終了します

  • ワーカースレッドに作業を行わせ、プログレスバーコンポーネントで定期的にrepaint()を呼び出します(これはスレッドセーフであることが保証されています)

  • プログレスバーには独自のpaintComponentがあります(EDTで自動的に呼び出されます)。必要に応じて、これは進行状況を測定するためにワーカースレッドによって更新される変数を読み取ることができます

  • ワーカースレッドが終了したら、invokeLater()を呼び出して、EDTで最後のクローズダウン関数を実行します。これにより、進行状況バーが非表示になり、その他のGUI関連のクリーンアップが実行されます。ユーザーに完了メッセージが表示されます。

于 2010-08-13T00:02:30.780 に答える