2

SwingUtilities.invokeLaterを使用してJFrameの更新を表示するスレッドがあります。スレッドの速度は調整可能であり、フルスピードに設定すると(更新の合間にスリープしない)、プログラムの速度が大幅に低下します。問題は、私のスレッドがJFrameのスレッドが消費できないSwingUtilities.invokeLaterイベントを生成しすぎていることだと思います。それで、以前に追加されたが消費されていないイベントを削除するためにスレッドでできることはありますか?または、SwingUtilities.invokeLaterを使用せずにJFrameを更新する他の方法を使用する必要がありますか?

前もって感謝します。

4

3 に答える 3

4

これは、にとって完璧な仕事かもしれませんSwingWorker。増分更新を公開し、SwingWorkerそれらをバッチ処理してパフォーマンスの問題を解決できます。

プロセスメソッドはイベントディスパッチスレッドで非同期に呼び出されるため、プロセスメソッドが実行される前にpublishメソッドへの複数の呼び出しが発生する可能性があります。パフォーマンスの目的で、これらのすべての呼び出しは、連結された引数を使用して1つの呼び出しにまとめられます。

EDTで実行するコードは、を実装して追加しますprocess()。更新のリストは引数で渡されます。

于 2012-10-28T23:31:53.600 に答える
3

イベントディスパッチスレッドが飽和状態になるのを避けたいようです。スイングタイマーの使用方法javax.swing.Timerで説明されているクラスには、「複数の保留中の発砲を合体させる」クラスが含まれています。これは、更新のペースを調整する別の方法である可能性があります。setCoalesce()ActionEvent

ここで述べたように、SwingWorkerは33Hzに制限されています。

于 2012-10-29T01:24:18.457 に答える
1

簡単なrepaint()を使用できますか?その利点は、複数の呼び出しが1つにマージされることです。

(詳細を追加)

GPSの位置を常に更新し、2つのテキストフィールドに表示しているとします。更新を行うためのスレッド:

run() {
  while (keepGoing) {
    Point myLocation = computeMyLocation();
    locationModel.setLocation(myLocation);
    locationComponent.repaint();
  }
}

次に、MyLocationComponentで

@Override
public void paintComponent(Graphics g) {
   Point myLocation = locationModel.getLocation();

   // you'd really want a NumberFormat
   latitudeTextArea.setText(String.valueOf(myLocation.y));
   longitudeTextArea.setText(String.valueOf(myLocation.x));

   super.paintComponent(g);
}

利点は、これによりモデルがビューから分割され(スレッドをコントローラーと考える場合、これはMVCです)、すべてのスレッドが機能する必要があることです。invokeLater()は必要ありません。欠点の1つは、スレッドが更新する必要のあるすべてのJComponentを認識している必要があることです。「実際の」シナリオでは、「コントローラー」(スレッド)またはモデルのいずれかから、再描画をトリガーするリスナーにイベントを発生させる可能性があります。

注:@trashgodが指摘しているように、LocationModelでは、更新がすぐに表示されるように、メソッドgetLocation()setLocation()メソッドを指定する必要があります。synchronized

于 2012-10-29T01:57:06.867 に答える