繁体   English   中英

java swing线程回调

[英]java swing thread callback

我正在尝试使用swing编写一些客户端/服务器应用程序。 我有线程通信问题。 我不明白如何将一些数据从EDT发送回正在运行的线程。

class SwingUI extends JFrame implements IUpdater{

    @Override
    public void askPermission(String str) {
        int i = JOptionPane.showConfirmDialog(this, str);
        //  (?)Send i back
    }

}

class Connection implements Runnable{

    IUpdater updater;

    Connection(IUpdater u){updater = u;}

    @Override
    public void run() {
        String command = "download_file"; //=getCommand(); from a socket
        if(command.equals("download_file")){

            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    updater.askPermition(command);
                }
            });
            //  (?)wait until user answers
            //  int answ = getAnswer();
            //  if answ == OK
            System.out.println("Sending_File");
            //  if answ == DENY
            //System.out.println("Denied");
        }
    }

}



interface IUpdater{
    void askPermission(String str);
}

我需要以某种方式从userUI获得响应。 也许不仅是int值,而且还有List对象。

例如,连接后,我需要在userForm中为某些客户端准备一些数据,然后将其发送。 我该怎么办?

Swingworker仅允许将数据发布到EDT或引发EDT监听的事件,而不接收消息。

另外,我必须使运行线程以某种方式等待。 我不确定在进行一些变量更改之前sleep(n)是一个好主意,但在这种情况下我不知道如何使用监视器,我应该吗。也许有一些设计模式可以解决此问题?

我敢肯定这是普遍的情况,但是我找不到任何信息。

线程仅执行Runnable,而不能发送/接收消息或值,Runnable则这样做。 但是您不能从仅接受String且不返回任何内容的接口方法中获取值。 因此,首先更新接口:

public interface IUpdater {
    int askPermission(String str);
}

接下来,定义一个可调用接口方法并存储结果的可运行对象:

import java.util.concurrent.CountDownLatch;
public class AskUser implements Runnable {

    final CountDownLatch userInput = new CountDownLatch(1);
    IUpdater updater;
    String command;
    volatile int result;

    @Override
    public void run() {

        try {
            result = updater.askPermission(command);
        } finally {
            userInput.countDown();
        }
    }
}

CountDownLatch使一个线程有机会等待另一个线程(或更准确地说,是让可运行对象到达某个状态)。 更新的Connection实现显示了这个小技巧:

public class Connection implements Runnable {

    IUpdater updater;
    Connection(IUpdater u){updater = u;}

    @Override
    public void run() {
        String command = "download_file"; //=getCommand(); from a socket
        if(command.equals("download_file")) {

            AskUser ask = new AskUser();
            ask.command = command;
            ask.updater = updater;
            SwingUtilities.invokeLater(ask);
            try {
                ask.userInput.await();
            } catch (Exception e) {
                // waiting for user input was interrupted
            }
            System.out.println("Result: " + ask.result);
        }
    }
}

通常,如果您在从Runnable获取值时遇到麻烦,请将Runnable设置为单独的类,看看是否可以解决该问题。 您可以使用一些技巧来实现快捷方式(因此不必为Runnable创建单独的类),但这需要特定的知识并且较难维护。
我经常使用CountDownLatch技巧来获取不同的Runnable来同步或了解彼此的状态。 给定适当的变量名,应该很清楚正在发生什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM