Swing线程中的Java操作

时间:2015-05-05 23:27:18

标签: java multithreading swing thread-safety

我有问题。 这是代码:

JButton buttonChangeServer = new JButton("Change server");
    buttonChangeServer.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
                getLobbies();
            }
        }
    });

private void getLobbies() {
    lobbyListModel.removeAllElements();
    statusLabel.setText("Connecting...");
    final ArrayList<LobbyInfo> lobbyInfos = 
            UserClient.getLobbies(host, action, null);
    if (lobbyInfos != null) {
        setLobbies(lobbyInfos);
        statusLabel.setText("Sucessfully got lobby list from " + getHost());
    }
    else {
        statusLabel.setText("Failed to connect to " + getHost());
    }
}

UserClient.getLobbies(host, action, null)方法如果无法建立连接,则执行3秒(超时)。 问题是这两个操作

lobbyListModel.removeAllElements();
statusLabel.setText("Connecting...");

在执行时不可见。

我认为问题是getLobbies()中的方法actionPerformed(ActionEvent e)在Swing线程中执行,并且直到getLobbies();执行结束才显示所有GUI操作

我的目标是在执行UserClient.getLobbies(host, action, null);之前和之后显示GUI的所有更改。我该如何管理?是否有一种简单的方法来展示它们?谢谢。

P.S。其中一个解决方案可能是在另一个线程中放置这个有潜力的长操作,如下所示:

private void getLobbies() {
        lobbyListModel.removeAllElements();
        statusLabel.setText("Connecting...");
        new Thread(new Runnable() {
            @Override
            public void run() {
                final ArrayList<LobbyInfo> lobbyInfos = 
                    UserClient.getLobbies(host, action, null);
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        if (lobbyInfos != null) {
                            setLobbies(lobbyInfos);
                            statusLabel.setText("Sucessfully got lobby list from " + getHost());
                        }
                        else {
                            statusLabel.setText("Failed to connect to " + getHost());
                        }
                    }
                });
            }
        }).start();
    }

它有效,但它相当复杂。有什么方法更容易吗?

1 个答案:

答案 0 :(得分:4)

  

其中一个解决方案可能是将这个可能很长的操作放在另一个线程中

是的,长时间的操作(或阻止操作)不应该在EDT上执行。

因此,您需要在分离的线程上执行长时间运行的任务。请查看Worker Threads and Swing Worker上Swing教程中有关此问题的Swing解决方案的部分。

当您的查询完成执行后,您可以&#34;发布&#34;结果,以便在更新Swing组件时在EDT上执行代码。