我有一个Observable类和一个Observer类。
这有点傻,但我的Observable类的方法notifyObserver(arg)永远不会调用我的Observer类的更新(Observable obj,Object arg)方法......
这是我的OBSERVABLE类:,它正在从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
答案 0 :(得分:0)
您如何编码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
}
});
答案 1 :(得分:0)
我刚刚发现了测试问题。
我把这些行放在我的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();
时,它会通知我们的CURRENT CLASS GPSFrame,而不是ServerBoard类。