2

インターフェイスJFrameを実装するがある場合、メソッドはイベント ディスパッチ スレッドで実行されますか?Observerupdate()

public class MyFrame extends JFrame implements Observer{
    @Override
    public void update(Observable o, Object arg) {
        //do gui stuff  
    }   
}

.

public class MyTask extends Observable implements Runnable{
    @Override
    public void run() {
        setChanged();
        notifyObservers("Update!");
    }
}
4

2 に答える 2

2

私が自分で見つけたように:

いいえ、メソッドThreadを呼び出した上で実行されます。notifyObservers()

メソッドのソース コードからわかるように、タスクを別のスレッドに渡すことなく、オブザーバーnotifyObservers()のメソッドを呼び出すだけです。update()

public void notifyObservers(Object arg) {
    /*
    * a temporary array buffer, used as a snapshot of the state of
    * current Observers.
    */
    Object[] arrLocal;

    synchronized (this) {
        if (!changed)
            return;
        arrLocal = obs.toArray();
        clearChanged();
    }

    for (int i = arrLocal.length-1; i>=0; i--)
        ((Observer)arrLocal[i]).update(this, arg);
    }
}
于 2013-09-09T14:17:51.393 に答える
0

あなたがやろうとしていると私が思うことをしたいなら、SwingWorkerを使うことができます。publish メソッドと process メソッドがあります。publish メソッドはメッセージを process メソッドに送信します。process メソッドは、SwingWorker の他の部分とは異なり、EDT 上で実行されます。

import java.awt.EventQueue;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JFrame;

import javax.swing.SwingWorker;


public class MyFrame extends JFrame {

    private static JTextField txtFld;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
                new UpdateSwingWorker().execute();
            }
        });    
    }

    private static void createAndShowGUI() {
        MyFrame frame = new MyFrame();

        JPanel panel = new JPanel(new BorderLayout());
        txtFld = new JTextField();
        panel.add(txtFld, BorderLayout.CENTER);

        frame.setSize(new Dimension(300,200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(300,200));
        frame.setLayout(new BorderLayout());
        frame.add(panel, BorderLayout.CENTER);

        frame.pack();
        frame.setVisible(true);     
    }

    private static class UpdateSwingWorker extends SwingWorker<Void, String> {

        @Override
        protected Void doInBackground() throws Exception {
            // Do your work...
            System.out.println("Thread in doInBackground: " + Thread.currentThread());
            publish("Updated");
            return null;
        }

        @Override
        protected void process(List<String> chunks) {
            System.out.println("Thread in process: " + Thread.currentThread());
            txtFld.setText(chunks != null ? chunks.get(0) : "");
        }

    }

}

または、本当に Observer パターンを使用したい場合は、notifyObservers 呼び出しを EventQueue の invokeLater 呼び出しでラップすることができます。このメソッドにより、Runnable はその run メソッドを EDT で発生させます。

フレーム:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class MyFrame2 extends JFrame implements Observer {
    private static JTextField txtFld;

    private static MyTask task = new MyTask();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
                new Thread(task).start();
            }
        });    
    }

    private static void createAndShowGUI() {
        MyFrame2 frame = new MyFrame2();
        task.addObserver(frame);

        JPanel panel = new JPanel(new BorderLayout());
        txtFld = new JTextField();
        panel.add(txtFld, BorderLayout.CENTER);

        frame.setSize(new Dimension(300,200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(300,200));
        frame.setLayout(new BorderLayout());
        frame.add(panel, BorderLayout.CENTER);

        frame.pack();
        frame.setVisible(true);     
    }

    @Override
    public void update(Observable o, Object arg) {

        System.out.println("Thread in update: " + Thread.currentThread());
        txtFld.setText((String) arg);
    }

}

仕事:

import java.awt.EventQueue;
import java.util.Observable;

public class MyTask extends Observable implements Runnable {

    @Override
    public void run() {
        // Do work
        System.out.println("Thread in run: " + Thread.currentThread());
        setChanged();

        // Notify the observers on the EDT.
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                System.out.println("Thread in invokeLater: " + Thread.currentThread());
                notifyObservers("Update!");
            }
        });
    }

}
于 2013-09-10T03:25:12.240 に答える