2014-01-06 94 views
0

我有一個Observable類和一個Observer類。JAVA - Observer永遠不會被通知Runnable

這是一個有點傻,但我可觀察類從來沒有叫我的觀察類的更新(可觀察OBJ,對象ARG)方法的方法notifyObserver(ARG)...

這裏是我的可觀測類:這是從GPS受體

public class GPSFrame extends Observable implements Runnable, SerialPortEventListener 
{ 
    static Thread myThread; 
    private CommPortIdentifier portid=null; 
    private SerialPort serialport; 
    private BufferedReader fluxgps; // Reading flow port where the GPS is connected 

    /** CONSTRUCTOR **/ 
    public GPSFrame() 
    {  
     myThread=new Thread(this); 
    } 

    public void start() 
    { 
     // The thread start automatically run() method 
     myThread.start(); 
    } 

    @Override 
    public void run() 
    { 
     try 
     { 
      // Driver initialization 
      Win32Driver driver=new Win32Driver(); 
      driver.initialize(); 

      GPSFrame gpscom=new GPSFrame(); 
      gpscom.listPort(); 
     } 
     catch (Exception e){ System.out.println("start "+e.toString()); }  
    } 

    // Scanning all available ports 
    public void listPort() 
    { 
     Enumeration<?> listport=CommPortIdentifier.getPortIdentifiers(); 

     while(listport.hasMoreElements()) 
     { 
      portid=(CommPortIdentifier)(CommPortIdentifier)listport.nextElement(); 
      if(portid.getPortType()==CommPortIdentifier.PORT_SERIAL) 
      { 
       // On lance la gestion des evenements sur le portid 
       this.portInitialization(portid.getName()); 
      } 
     } 
    } 

    public void portInitialization(String portcom) 
    { 
     // ... 
    } 

    public void retrieveGpsFrame() 
    { 
     String rawframe=new String(); 
     try 
     { 
      rawframe=(String)fluxgps.readLine(); 
      String[]gpsframe=rawframe.split(","); 
      // We are doing a pre-selection of the frame 
      if(gpsframe[0].equals("$GPGGA") || gpsframe[0].equals("$GPRMC")) 
      { 
       /* IMPORTANT - DON'T FORGET SETCHANGED() or GPSFrame'll never 
       * notify UPDATE() ServerBoard method - We'll never see any changes */ 
       System.out.println(rawframe); 
       setChanged(); 
       notifyObservers(rawframe); 
      } 
      else 
      { 
       gpsframe=null; 
      } 
     } 
     catch (IOException e) { e.printStackTrace(); } 
    } 
} 

這裏獲取GPS Frame是我的觀察器類:正在接收和顯示...什麼!

public class ServerBoard extends JFrame implements Observer 
{ 
    [...] 

    // RETRIEVE GPS FRAMES 
    public void retrieveGPSFrame() 
    { 
     gpsframe = new GPSFrame(); 
     gpsframe.addObserver(this); 
     gpsframe.start(); 
    } 

    // UPDATE THE JTEXTAREA AND CLIENT 
    public void update(Observable obj, Object arg) 
    { 
     messagearea.append("Affiche moi ce message"); 
     if (arg instanceof String) 
     { 
      gpsdata = (String) arg; 
      System.out.println(gpsdata); 
      messagearea.append(gpsdata); 
      tcpserver.sendMessage(gpsdata); 
     } 
    } 

    public void serialEvent(SerialPortEvent event) 
    { 
     // Gestion des evenements sur le port 
      // On ne fait rien sauf quand les donnees sont disponibles 
     switch(event.getEventType()) 
     { 
      case SerialPortEvent.DATA_AVAILABLE: 
       this.retrieveGpsFrame(); // Si les datas sont dispo, on lance la lecture 
       break; 
      default: 
       break; // On ne fait rien sinon  
     } 
    } 
} 

我的logcat沒有錯誤。 當我以調試模式啓動我的應用程序時,它永遠不會經歷更新方法。

你能幫助我嗎?

提前,謝謝。

問候,

Tofuw

+0

和'notifyObservers'被調用? – nachokk

+0

是的,notifyObservers被調用。這部分沒有問題。 – Tofuw

回答

0

我我剛剛通過測試發現了我的問題。

我已經把這些線在我的run方法(可觀測類):

setChanged(); 
notifyObservers("Something to show"); 

和它的作品。通知OBSERVER類,並向我顯示JTextArea上的文本。 現在,我只是重新組織我所有的代碼...

對於那些遇到同樣問題的人,我會在重組我的代碼後立即發佈答案。

非常感謝您的回答反正@xiaowang :)

編輯:解

的問題是非常愚蠢的。我們只需要替換這個run()方法

@Override 
public void run() 
{ 
    try 
    { 
     // Driver initialization 
     Win32Driver driver=new Win32Driver(); 
     driver.initialize(); 

     GPSFrame gpscom=new GPSFrame(); 
     gpscom.listPort(); 
    } 
    catch (Exception e){ System.out.println("start "+e.toString()); }  
} 

通過這樣的:

@Override 
public void run() 
{ 
    try 
    { 
     // Driver initialization 
     Win32Driver driver=new Win32Driver(); 
     driver.initialize(); 

     this.listPort(); 
    } 
    catch (Exception e){ System.out.println("start "+e.toString()); }  
} 

說明:

當我做GPSFrame gpscom=new GPSFrame();,我創建了一個新對象 gpscom,這父母是我目前的班級,GPSFrame。

雖然調用gpscom.listPort();,它通知我們的CURRENT CLASS GPSFrame,而不是類ServerBoard。

0

你如何編寫你的notifyObservers(rawframe)方法?

嘗試修復它2種方式:

1)檢查

if(gpsframe[0].equals("$GPGGA") || gpsframe[0].equals("$GPRMC")) 
{notifyObservers(rawframe);} 

已執行和notifyObservers()調用。

2)檢查在notifyObservers(),收聽者的更新方法

update(Observable obj, Object arg) 

正確調用。

更新:

我覺得你還沒有真正理解觀察者設計模式,顯然,我拿起代碼JDK AbstractButton中幫你,看看它是如何處理

//AbstractButton implementation like follwing: 

//the button use a ListenerList hold Listeners 
protected EventListenerList listenerList = new EventListenerList(); 

public void addActionListener(ActionListener l) { 
    listenerList.add(ActionListener.class, l); 
} 

//notify Listeners to update 
protected void fireActionPerformed(ActionEvent event) { 
    Object[] listeners = listenerList.getListenerList(); 
    ActionEvent e = null; 
    // Process the listeners last to first, notifying 
    // those that are interested in this event 
    for (int i = listeners.length-2; i>=0; i-=2) { 
     if (listeners[i]==ActionListener.class) { 
      ((ActionListener)listeners[i+1]).actionPerformed(e); 
     } 
    } 
} 

//observers ,registry to Button, do process in actionPerformed() 
JButton btnLogin = new JButton("Login"); 
btnLogin.addActionListener(new ActionListener(){ 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     //do process 

    } 
}); 
+0

嗨,謝謝你回覆@曉望。我不需要編寫notifyObserver代碼,因爲它是一個可觀察的方法。我檢查了你給我看的兩點。 1)正常執行,notifyObservers()被調用。 2)更新方法從未被調用過。 – Tofuw

+0

您必須編寫notifyObserver方法,在其中調用偵聽器的更新方法。請參閱更新。 – wangdq

相關問題