[英]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.