Java GUI 锁定 - boolean 值未按预期工作?

标签 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();
 ...

最佳答案

您的代码在 Swing 事件线程上调用 while (...) 循环,公然违反了 Swing 线程规则。不要那样做。而是使用 SwingWorker。通过向 SwingWorker 添加 PropertyChangeWorker,您可以轻松收到通知,一旦完成,就可以通过在工作线程上调用 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();
        }
    }
}

关于Java GUI 锁定 - boolean 值未按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34048391/

相关文章:

java - 将图像加载到 JLabel 中不起作用

android - 测试互联网连接 Android

java - Kruskal 算法 - 按升序对邻接矩阵进行排序

java - 如何使用restfb接受好友请求

Java Swing - 将 JLabel 中的图像放置到/高于第二个 JLabel( map 、播放器指示器)

java - JList行显示

java - Spring Boot jsp文件未找到错误404奇怪的前缀

java - 如何在 Apache HttpClient 中使用 SSL 客户端证书?

Java 套接字和丢弃的连接

c# - 如何使用C#启用禁用的无线网卡