我正在编写一个连接各种TCP网络设备的程序。 GUI是使用JavaFX制作的。整个连接部分都在自己的包装中#34; Network"。粗略地描述,它看起来像这样:(我不太了解UML,没有责备大家:/ - 我只需要一种方法来快速描述我的程序结构的外观)。 http://i.stack.imgur.com/PSdsH.jpg
好吧,这是怎么回事: TCP类存储在" NetworkManager"中的同步列表中。这些类包含有关连接的信息(已收到多少数据,ip,mac等)。 Rcv-Thread不断尝试接收数据。
好吧,这就是我想要的: 一旦Rcv-Thread收到特定消息,就应该调用控制器来做某事(GUI刷新或其他)。此外,控制器应与“网络”保持分离。模块 - >它在另一个项目中重复使用。我想通过自定义事件实现此行为。简而言之: TCP-Rcv-Thread需要能够向Controller提供信息。但我真的不知道如何让它全部工作。让我们看看我在哪里:我在" Network"中有一个事件类。模块。
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);
}
}
Controller(此类应对自定义事件作出反应)实现Listener:
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-列表中的类)。我尽可能多地阅读有关问题的内容,但无法弄清楚如何让它发挥作用。我错过了什么?
edit1: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()方法。
答案 0 :(得分:0)
好的,天以后我自己想出来了。 主要问题是我无法从Controller调用Rcv-Thread的addXListener()方法。我把自定义事件的东西从Rcv-Thread中取出并移动到TCP-Class。现在我可以将Listener添加到这些类中。如果我想从Rcv-Thread激发一个事件,我只需从它的超类(TCP-Class)调用fireHandlerMethod() - 一切都按预期工作。