1

別のActionListenerクラスからアクションリスナーを実装する方法がわかりません。アプリケーションをいくつかのクラスに分けました。メインクラスはFrameクラスを呼び出して、すべてのボタンを備えたGUIを作成します。ボタンが押されたときに、アクションを実行するためにActionListenerメソッドにデータを送信する必要があります。必要なデータを送信できないよりもFrameクラスにActionListenerを追加した場合、main()メソッドにActionListenerを追加した場合、Frameクラスを呼び出した後、不器用に感じます。コードは次のとおりです。publicclassMain{

public static Client klijent;

public static void main(String[] args) {

    FrameBuilder frame= new FrameBuilder();
    frame.frameBuild();
    frame.send.addActionListener(new SendBttnListener(ClientBuilder(klijent,frame.txt.getText())));

    try {
        frame.statLabel.setText(InetAddress.getLocalHost().getHostAddress());
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }

    Udp udp;
    // klijent = null;

    while(true){
        klijent=new Client();
        udp=new Udp();

        klijent=udp.packageIN();
        if(klijent!=null){
            frame.statLabel.setText("");
            String str=new String(klijent.getBajt(),0,klijent.bajt.length);
            str=str.trim();
            frame.statLabel.setText(str+"@...@"+klijent.clientAddress.toString()+":"+klijent.clientPort+"-->Duljina:"+klijent.bajt.length);
        }
    }
}

public static Client ClientBuilder(Client klijent2, String str){

    klijent.setBajt(str.getBytes());

    return klijent2;
}

ご覧のとおり、クライアントオブジェクトは大幅に変更される可能性があり(UDPサーバー)、次のパッケージを待つときにクリアされます。後で、クライアントのリストを実装して、FrameクラスにActionリスナーを追加するのはばかげているようです。GUIを構築するためのseparetクラスを作成したときに、うまくいきませんでしたか?何かアドバイス?

前もって感謝します....

4

1 に答える 1

3

送信するメソッドは、独自の実装でラップする必要があります。これはシングルトン実装にするか、ラッピング アクション リスナーへの参照として渡すことができます。

ボタン アクション リスナーは、ボタンのコンテキスト内からのみ管理する必要があります。ボタン コンテキストの外からアクセスできるようにする必要はありません (つまり、これを実行できるとは思いませんframe.send.addActionListener(...))。 send リクエストを達成するだけで...

メッセージを「送信」する手段を提供するフレームに渡すことができるクラスまたはインターフェイスが必要です。

public interface Sender {
    public void sendMessage(String message); // Or what ever parameter you want...
}

実装の参照をフレームに渡します...

Sender sender = new ImplementationOfSender();
frame.setSender(sender); // It could also be passed to the constructor

フレーム内で、アクション リスナーをボタンにアタッチし、トリガーされると、送信者にアクセスしてメッセージを送信します...

send.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        Sender sender = getSender();
        if (sender != null) {
            sender.sendMessage(...);
        }
    }
});

今、あなたのプログラムはあなたの目の前で爆発するでしょう...

これにより、プログラムが途中で停止し、UI がハングしたように見えます。

while(true){
    klijent=new Client();
    udp=new Udp();

    klijent=udp.packageIN();
    if(klijent!=null){
        frame.statLabel.setText("");
        String str=new String(klijent.getBajt(),0,klijent.bajt.length);
        str=str.trim();
        frame.statLabel.setText(str+"@...@"+klijent.clientAddress.toString()+":"+klijent.clientPort+"-->Duljina:"+klijent.bajt.length);
    }
}

UI とのすべての対話は、Event Dispatching Thread (AKA EDT)のコンテキスト内から行う必要があります。ループなどのブロック アクションは、EDT のコンテキスト内から実行しないでください。

Concurrency in Swingを読んだことがあるでしょう。

あなたのプログラムがおそらくまだ爆発的に発展している唯一の理由は、それを起動したときに、UI の作成を EDT に同期していないという事実です。

Swing Single Threading Ruleを読みたいと思うかもしれません

于 2012-10-04T00:31:57.783 に答える