如何使用事件解耦我的网络管理员?

时间:2014-09-12 05:53:22

标签: java javafx decoupling custom-events

我正在编写一个连接各种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()方法。

1 个答案:

答案 0 :(得分:0)

好的,天以后我自己想出来了。 主要问题是我无法从Controller调用Rcv-Thread的addXListener()方法。我把自定义事件的东西从Rcv-Thread中取出并移动到TCP-Class。现在我可以将Listener添加到这些类中。如果我想从Rcv-Thread激发一个事件,我只需从它的超类(TCP-Class)调用fireHandlerMethod() - 一切都按预期工作。