Java GUI锁定 - 布尔值无法按预期工作?

时间:2015-12-02 16:51:54

标签: java swing networking

我正在制作基于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();
 ...

1 个答案:

答案 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();
        }
    }
}