我正在编写一个与各种 TCP 网络设备连接的程序。GUI 是使用 JavaFX 制作的。整个连接部分在它自己的包“网络”中。粗略地描述一下,它看起来像这样:(我对 UML 了解不多,没有责备 plaese :/ - 我只需要一种方法来快速描述我的程序结构的外观)。http://i.stack.imgur.com/PSdsH.jpg
好吧,就是这样:TCP 类存储在“NetworkManager”的同步列表中。这些类保存有关连接的信息(接收到多少数据、ip、mac 等)。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() 方法。