2013-09-09 3 views
2

Если у меня есть JFrame, который реализует интерфейс Observer, будет ли выполняться метод update() в потоке отправки событий?Будет ли реализован метод обновления наблюдателя в потоке отправки событий

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!"); 
    } 
} 

ответ

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); 
    } 
} 
0

Если вы хотите делать то, что, как я думаю, вы пытаетесь сделать, вы можете использовать SwingWorker. Он имеет метод публикации и метод публикации. Метод публикации отправит сообщения методу процесса. Метод обработки, в отличие от остальной части 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 позвонить в invokeLater вызова EventQueue в. Этот метод заставляет Runnable использовать метод запуска в 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!"); 
      } 
     }); 
    } 

}