Question

I have an Observable class and an Observer class.

It is a bit silly, but the method notifyObserver(arg) of my Observable class NEVER call the update(Observable obj, Object arg) method of my Observer class...

Here is my OBSERVABLE class : which is retrieving GPS Frame from a GPS Receptor

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

Here is my OBSERVER class : which is receiving and showing... nothing !

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     
        }
    }
}

There is no errors in my logcat. When I launch my applications in debug mode, it never goes through the update method.

Can you help me please ?

In advance, thank you.

Regards,

Tofuw

Was it helpful?

Solution 2

I've just found my problem with a test.

I've put these lines on my RUN method (OBSERVABLE Class) :

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

And it works. The OBSERVER class was notified, and show me the text on the JTextArea. Now, I've just to reorganize all my code to do so...

For those who encounter the same problem, I'll post an answer as soon as I reorganized my code.

Thanks a lot for your answers anyway @xiaowang :)

EDIT : SOLUTION

The problem is really silly. We simply have to replace this run() method

@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()); }       
}

By this :

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

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

EXPLANATION :

When I do GPSFrame gpscom=new GPSFrame();, I create a new object gpscom, which parent is my current class, GPSFrame.

While calling gpscom.listPort();, it notify our CURRENT CLASS GPSFrame, not the class ServerBoard.

OTHER TIPS

how you code your notifyObservers(rawframe) method ?

Try to fix it 2 ways:

1) check

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

has executed and notifyObservers() called.

2) check in notifyObservers(),listener's update method

update(Observable obj, Object arg)

called correctly.

update:

I think you haven't really understand the observer design pattern clearly,I pick up code from JDK AbstractButton to help you,see how it deal with

//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

    }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top