JAVA - Обозреватель никогда не уведомляется, пока Observable реализован Runnable

У меня есть класс Observable и класс Observer.

Это немного глупо, но метод notifyObserver(arg) моего класса Observable НИКОГДА не вызывает метод update(Observable obj, Object arg) моего класса Observer...

Вот мой НАБЛЮДАЕМЫЙ класс: который извлекает кадр GPS из приемника 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(); }  
    }
}

Вот мой класс OBSERVER: который получает и показывает... ничего!

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

2 ответа

Решение

Я только что нашел мою проблему с тестом.

Я поместил эти строки в мой метод RUN (OBSERVABLE Class):

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();, это уведомляет наш ТЕКУЩИЙ КЛАСС GPSFrame, а не класс ServerBoard.

Как вы кодируете свой метод notifyObservers(rawframe)?

Попробуйте это исправить двумя способами:

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

    }
});
Другие вопросы по тегам