我正在制作基于Java的服务器应用程序。出于某种原因,当我从服务器检索文件列表时,我的GUI被锁定。我向服务器发送消息“listFiles”,然后服务器以“LIST”响应 - 这是执行下面的代码时。
private Boolean wait = true;
// Handle server output.
private class ServerOutput implements Runnable {
public void run() {
String serverMsg;
while ((serverMsg = reader.nextLine()) != null) {
try {
if (serverMsg.equals("LIST")) {
wait = true;
fileList = new ObjectInputStream(socket.getInputStream()).readObject();
fileArray = (File[]) fileList;
for(File file : fileArray){
System.out.println(file.getName());
}
wait = false;
}
public Boolean getState(){
return wait;
}
public File[] getFileList(){
return fileArray;
}
...
GUI应该停留在while循环中,直到“wait = true”。有时候它会起作用,有时它只是卡在循环中,即使客户端肯定收到了fileList,因为它成功地将其打印出来。
以下是连接到连接按钮的动作侦听器的代码:
try {
fc = new FileClient(serverAddress, serverPort);
fc.send("listFiles","null");
while (fc.getState()) {
}
File[] fileList = fc.getFileList();
...
答案 0 :(得分:3)
你的代码在Swing事件线程上调用while (...)
循环,公然破坏了Swing线程规则。不要这样做。而是使用SwingWorker。您可以通过向其添加PropertyChangeWorker轻松地通知SwingWorker何时完成,一旦完成,然后通过调用worker上的get()
来提取它返回的结果。 SwingWorker Tutorial可以向您显示详细信息。
您的代码可能类似于:
@Override
public void actionPerformed(ActionEvent e) {
// create the SwingWorker
MyFileWorker myFileWorker = new MyFileWorker();
// attach a PropertyChangeListener to it
myFileWorker.addPropertyChangeListener(new MyFileWorkerListener());
// and run the worker
myFileWorker.execute();
}
和其他地方:
private class MyFileWorker extends SwingWorker<File[], Void> {
// must initialize the readers, sockets....
// probably with data passed into this worker's construtor
private BufferedReader reader = null; // fix this
private Socket socket = null; // fix this
@Override
protected File[] doInBackground() throws Exception {
String serverMsg;
while ((serverMsg = reader.readLine()) != null) {
if (serverMsg.equals("LIST")) {
File[] fileArray = (File[]) new ObjectInputStream(socket.getInputStream()).readObject();
return fileArray;
}
}
// if LIST never found
return null;
}
}
private class MyFileWorkerListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() != SwingWorker.StateValue.DONE) {
return;
}
MyFileWorker myFileWorker = (MyFileWorker) evt.getSource();
try {
// get File array
files = myFileWorker.get();
// here notify GUI that files have been found
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}