0

我正在编写一个与各种 TCP 网络设备连接的程序。GUI 是使用 JavaFX 制作的。整个连接部分在它自己的包“网络”中。粗略地描述一下,它看起来像这样:(我对 UML 了解不多,没有责备 plaese :/ - 我只需要一种方法来快速描述我的程序结构的外观)。http://i.stack.imgur.com/PSdsH.jpg

好吧,就是这样:TCP 类存储在“NetworkManager”的同步列表中。这些类保存有关连接的信息(接收到多少数据、ip、ma​​c 等)。Rcv-Thread 不断尝试接收数据。

好吧,这就是我想要的:一旦 Rcv-Thread 接收到特定消息,就应该调用控制器来执行某些操作(GUI 刷新或其他)。此外,控制器应该与“网络”模块保持分离->它在另一个项目中被重用。我想通过自定义事件来实现这种行为。简而言之:TCP-Rcv-Thread 需要能够向 Controller 提供信息。但我真的不知道如何让这一切正常工作。让我们看看我在哪里:

  • 我在“网络”模块中有一个事件类。

    import java.util.EventObject;
    
    public class XEvent extends EventObject{
      String message;
        public XEvent(Object source, String message) {
        super(source);
        this.message = message;
      }
    
    public String getMessage() {
        return message;
     }
    }  
    
  • 我在“网络”模块中有一个监听器类。

     import java.util.EventListener;
        public interface XListener extends EventListener{
        void handlerMethod1(XEvent event);
        void handlerMethod2(XEvent event);
    }
    
  • 我试图准备我的 Rcv-Thread 来触发事件:

    import javax.swing.event.EventListenerList;
    import java.io.IOException;
    
    public class ReceiveDataThread implements Runnable {
    protected EventListenerList listenerList = new EventListenerList();
    }
    
    protected void addXListener(XListener xListener) {
            listenerList.add(XListener.class, xListener);
        }
    
    
    
    protected void removeListener(XListener xListener) {
            listenerList.remove(XListener.class, xListener);
        }
    
    protected void fireHandlerMethod1(String message) {
        XEvent event = null;
        Object[] list = listenerList.getListenerList();
        for (int i = 0; i < list.length; i += 2) {
            if (list[i] == XListener.class) {
                if (event == null) event = new XEvent(this, message);
                XListener l = (XListener) list[i + 1];
                l.handlerMethod1(event);
            }
        }
    }
    
    protected void fireHandlerMethod2(String message) {
        XEvent event = null;
        Object[] list = listenerList.getListenerList();
        for (int i = 0; i < list.length; i += 2) {
            if (list[i] == XListener.class) {
                if (event == null) event = new XEvent(this, message);
                XListener l = (XListener) list[i + 1];
                l.handlerMethod2(event);
            }
        }
    }
    
    @Override
    public void run() {
        String s;
        while (!stopThread) {
            s = receiveData();
            System.out.println("test");
            fireHandlerMethod1(s);
        }
    }
    
  • 控制器(这个类应该对自定义事件做出反应)实现监听器:

    public class Controller implements Initializable, XListener {
    @Override
    public void handlerMethod1(XEvent event) {
        System.out.println("Event1: " + event.getMessage());
    }
    
    @Override
    public void handlerMethod2(XEvent event) {
    
     }
    }
    

从那里开始,我真的不知道如何让我的事件(从我的 Rcv-Thread 触发)被我的控制器类注意到。我想我必须通过控制器类为每个 Rcv-Thread 对象添加一个侦听器(就像我使用 ButtonListener 时一样,...)。问题是:从我的 TCP 类我无法访问 Rcv-Thread-object 的 addXListener 方法 -即使设置为公共(但我可以从列表中访问 Rcv-Thread-Classes)。我试图尽可能多地阅读有关该问题的内容,但无法弄清楚如何使其正常工作。我错过了什么?

编辑1:TCP类:

public class TCPClass{
private Thread receiveDataThread;
private String MAC;     
private InetAddress IP;
private Socket socket = new Socket();  
private int tcpSendPort;
private int timeOut = 10;    
private ObjectOutputStream objectOutputStream;
private BufferedReader bufferedReader;
private String connectionStatus = "offline";  


public TCPClass(DatagramPacket datagramPacket) {
    IP = datagramPacket.getAddress();
    setConnectionStatusOnline();
    tcpSendPort = 50000 + NetworkManager.getNumberOfConnections();
    MAC = extractMac(datagramPacket);
}
    public void connect(int tcpPort) {
    try {
        socket = new Socket(IP, tcpPort, null, tcpSendPort);
        bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        receiveDataThread = new Thread(new ReceiveDataThread(this));
        receiveDataThread.start();
        InputStreamReader(socket.getInputStream()));
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("on MAC: " + getMAC() + "\non Device:" + toString());
    }
    if (socket.isConnected()) {
        setConnectionStatusConnected();
    }
}
}

NetworkManager 创建一个 TCPClass 对象并调用 connect() 方法。

4

1 回答 1

0

好的,几天后我自己弄清楚了。主要问题是我无法从控制器调用 Rcv-Thread 的 addXListener() 方法。我将自定义事件的东西从 Rcv-Thread 中取出,并将其移至 TCP-Class。现在我可以将监听器添加到这些类中。如果我想从 Rcv-Thread 触发事件,我只需从其超类(TCP-Class)调用 fireHandlerMethod() - 一切都按预期工作。

于 2014-09-15T07:38:53.813 回答