0

実際には複数の質問があります。

与えられたモデル ビューとコントローラー。(私のものはたくさん結合されています-ビューはそのコントローラーを知っており、コントローラーはビューを知っています。)

コントローラーの新しいスレッドは基本的な方法で起動できnew Runnable(){ (...) run(){}}ますか?それを適切に行うには、何らかの「スイング方法」で実行する必要がありますか? 多分TimerまたはとinvokeLater()

2番目のことは、新しいスレッドが開始されたと仮定して、ビューで直接操作し、いくつかJTextFieldのs(など)を設定setThatTextFieldWithNewValue(msg)すると、必要なスレッドから呼び出された結果として同期する必要があるなどのメソッドですか?もしそうなら、結合を減らし、必要な同期について考えるのに費やす時間を減らすより良いアプローチはありますか?

4

4 に答える 4

2
  1. SSCCEをより早く投稿するために、MVCを作成、管理、通知する方法はいくつかあります。

  2. Runnable#Threadは非常に快適で安定した明確な方法ですが、Swing GUIへのすべての出力をにラップすることをお勧めします。これには、invokeLaterスレッドセーフなメソッドが含まれます。setTextappend

  3. Kumar Vivek Mitra(+1)がSwingWorkerがあると述べたが、についての最も深い知識が必要だったので、SwingWorkerから例外を取得Java essential classesする方法にいくつかの問題がありますexceptions recycle

  4. MVCについては、私の類似した質問に役立つかもしれません

于 2012-07-12T07:43:17.073 に答える
2

Swing はスレッドセーフではありません

1. UI スレッドはイベント ディスパッチャ スレッドであり、Gui の作業を担当します。

2. UI スレッドの外部で非 Ui スレッドを操作してみます。

3. もちろん、UI スレッド内からスレッドを起動することもできますが、UI スレッドから除外することをお勧めします。そうしないと、GUI が応答しないように見える場合があります。

(つまり、UI 作業を担当する UI スレッドの非 UI スレッド OUT での非 UI 作業)

4.スイングの方法もあります... SwingWorkerを使用します。これは、 UI スレッドと非 UI スレッド間の同期を処理します。

編集部分:

// フレーム/JFRAME にコンポーネントを直接追加するのは良くないことに注意してください。

public class MyClass extends JFrame{

private final JButton b;

 public MyClass(){

  this.setSize(300,300);
  this.setComponent();
  this.setHandler();
}

public void setComponent(){

  b = new JButton("Click");
  this.add(b);

}

public void setHandler(){

  b.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {

            // Do whatever you want...      

    }
});

}

public static void main (String[] args) { 
      EventQueue.invokeLater(new Runnable(){    // UI THREAD
        public void run(){

         MyClass s = new MyClass();   
         s.setVisible(true);
        }

      });
   }
}

メイン メソッドは Swing では短命です。メイン メソッド() は、GUI の構築をイベント ディスパッチャー スレッド (EDT) にスケジュールしてから終了します。そのため、GUI を処理するのは EDT の責任です。そのため、非 UI スレッドでの非 UI 作業を EDT から遠ざけることを常にお勧めします。

于 2012-07-12T07:09:51.477 に答える
1

スイング中のものすべて EventQueue で実行する必要があります。swing から呼び出されたメソッドがある場合は、(アクション リスナーのように) そこで既に実行されています。イベント キューにいるかどうかわからない場合は、EventQueue.isDispatchThread()が教えてくれます。そうでないことがわかっている場合は、結果を確認する必要がある場合は、EventQueue.invokeLater()またはを使用してスイング クラスまたはメソッドを参照してください。invokeAndWait(これはメソッドから実行する必要がありますmain。)

これには十分注意してください。コードを確認する必要があります。そうでない場合、私の経験では、swing UI は少し不安定で、再現できない奇妙な点が時々あります。コードの各行に注目するのは簡単なことではありません。

実際、あります。EventQueue ですべてを実行すれば、心配する必要はありません。とにかく、swing 以外で多くの作業を行っているわけではありません。もしそうなら、マルチスレッドの問題を避けるために速度を落とす価値があるでしょう。Swing 以外の作業が大規模だが単純な場合は、SwingWorker クラスを使用します。高度に制御された条件下で余分なスレッドを提供し、多くの悲しみを救うはずです.

あなたのクラス (View と Controller) はスレッドから独立しており、1 つのスレッドで実行されているすべてが正常に動作するはずです。クラスとスレッドを混同しないでください。(正直に言うと、Controller に全方向にスレッドを起動させたくなるかもしれませんが、非常に注意して、マルチスレッドについて知っておくべきことをすべて知っておく必要があります。)

マルチスレッドを行う場合、EventQueue は、そこでのみ参照されるフィールドを保護する必要がないため、少し便利です。これは、危険な海に浮かぶシングル スレッドの島です。一方、同期は行わないでください。UIをブロックします。そこからスレッドを起動できますが、ブロックを回避するためだけに必要になる場合があります。(マルチスレッド化を開始すると、停止するのは困難です。)

于 2012-07-12T19:55:42.037 に答える
0

最も簡単な方法は次のとおりです。

        SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {

            // Run your code here.

        }
    });

より複雑なタスクの場合 (プロセス チャンクを UI スレッドに送信し、jobFinished に応答します):

    new SwingWorker<String, String>() {


        @Override
        protected void done() {

        }

        @Override
        protected void process(List<String> arg0) {


        }

        @Override
        protected String doInBackground() throws Exception {


        }


    }.execute();
于 2012-07-12T07:58:11.700 に答える