0

さまざまな TCP ネットワーク デバイスに接続するプログラムを書いています。GUI は JavaFX を使用して作成されます。接続部分全体が独自のパッケージ「Network」に入っています。大まかに説明すると、次のようになります。http://i.stack.imgur.com/PSdsH.jpg

TCP クラスは「NetworkManager」の同期されたリストに保存されます。これらのクラスは、接続に関する情報 (まだ受信したデータの量、ip、ma​​c など) を保持します。Rcv-Thread は常にデータを受信しようとします。

まあ、これは私が望むものです: Rcv-Thread が特定のメッセージを受信するとすぐに、コントローラーを呼び出して何かを実行する必要があります (GUI の更新など)。また、コントローラーは「ネットワーク」モジュールから分離したままにする必要があります->別のプロジェクトで再利用されます。カスタム イベントを通じてこの動作を実現したいと考えています。つまり、TCP-Rcv-Thread はコントローラーに情報を提供できる必要があります。しかし、私はそれをすべて機能させる方法を本当に知りません。私がどこにいるか見てみましょう:

  • 「ネットワーク」モジュールにイベント クラスがあります。

    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 メソッドにアクセスできないことです - public に設定されていても(ただし、リストから Rcv-Thread-Classes にアクセスできます)。問題についてできる限り読み込もうとしましたが、これを機能させる方法がわかりません。私は何が欠けていますか?

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() メソッドを呼び出します。

4

1 に答える 1

0

わかりましたので、数日後、私は自分でそれを理解しました。主な問題は、コントローラから Rcv-Thread の addXListener() メソッドを呼び出せなかったことです。Rcv-Thread から Custom Event のものを取り出し、それを TCP-Class に移動しました。これで、リスナーをこれらのクラスに追加できるようになりました。Rcv-Thread からイベントを発生させたい場合は、そのスーパークラス (TCP-Class) から fireHandlerMethod() を呼び出すだけで、すべてが期待どおりに機能します。

于 2014-09-15T07:38:53.813 に答える