Swing线程中的Java操作

Swing线程中的Java操作,java,multithreading,swing,thread-safety,Java,Multithreading,Swing,Thread Safety,我有个问题。 代码如下: JButton buttonChangeServer = new JButton("Change server"); buttonChangeServer.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getLobbies(); }

我有个问题。 代码如下:

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());
    }
}
在执行时不可见

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

我的目标是显示在执行
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();
    }
private void getLobbies(){
lobbyListModel.removeAllElements();
statusLabel.setText(“连接…”);
新线程(newrunnable()){
@凌驾
公开募捐{
最终ArrayList游说信息=
getLobbies(主机,操作,null);
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
if(lobbyInfos!=null){
setLobbies(lobbyInfos);
statusLabel.setText(“成功地从“+getHost()获取了大厅列表”);
}
否则{
statusLabel.setText(“未能连接到”+getHost());
}
}
});
}
}).start();
}
这是可行的,但相当复杂。有没有更简单的方法

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

是的,长操作(或阻塞操作)不应在EDT上执行

因此,您确实需要在单独的线程上执行长时间运行的任务。有关此问题的Swing解决方案,请查看上Swing教程的部分

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

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

是的,长操作(或阻塞操作)不应在EDT上执行

因此,您确实需要在单独的线程上执行长时间运行的任务。有关此问题的Swing解决方案,请查看上Swing教程的部分

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

SwingWorker不难——我建议研究它。SwingWorker不难——我建议研究它。
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();
    }