1

我不知道如何从单独的 ActionListener 类中实现动作监听器。我将应用程序分为几个类。Main 类调用 Frame 类来创建带有所有按钮的 GUI。现在,当按下按钮时,我需要向 ActionListener 方法发送一些数据以使其完成工作。如果我在 Frame 类中添加 ActionListener 而无法发送所需的数据,如果我在 main() 方法中添加 ActionListener,在调用 Frame 类之后会感觉很笨拙。下面是代码: public class Main {

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(...)),因为调用者不应该关心如何发送请求就实现了,只是……

我有一个类或接口,您可以将其传递给您的框架,为它提供“发送”消息的手段。

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 的所有交互都必须在事件调度线程 (AKA EDT)的上下文中完成。任何阻塞操作,例如你的循环,都不应在 EDT 的上下文中执行

我会阅读Swing 中的 Concurrency

您的程序可能已经爆炸的唯一原因是当您启动它时,您还没有将 UI 的创建同步到 EDT。

您可能想阅读Swing Single Threading Rule

于 2012-10-04T00:31:57.783 回答