Java程序“很快冻结”

时间:2013-07-13 19:34:32

标签: java swing event-dispatch-thread

我是java的新手,它不是我的第一个编程语言。 我实际上尝试编写下载所有文件的下载程序,直到服务器上的版本与客户端版本相同。

程序运行良好,但这是我无法解决的问题。

如果我运行此代码:

private void updateContent()
{
    DownloadButton.setEnabled(false);
    SaveLocationButton.setEnabled(false);
    UpdateText.setText("Update to Version " + ServerVersionNumber + "...");
    UpdateText.setForeground(new Color(200, 150, 0, 255));
    ProgressText.setText("(1/2) Files will be downloaded");
    ProgressText.setForeground(new Color(200, 150, 0, 255));
    LoadingBar.setStringPainted(true);

    for(int i = 1; i < (ServerVersionNumber - LocalVersionNumber + 1); i++)
    {
        int CurrentUpdateFile = LocalVersionNumber + i;


        try 
        {
            URL FileURL = new URL(Host + CurrentUpdateFile + ".zip");

            try {
                FileURL.openConnection();


                InputStream reader = FileURL.openStream();
                FileOutputStream writer = new FileOutputStream(ContentSaveDirectory + CurrentUpdateFile + ".zip");

                byte[] buffer = new byte[153600];
                int bytesRead = 0;


                while ((bytesRead = reader.read(buffer)) > 0)
                {  
                    writer.write(buffer, 0, bytesRead);
                    buffer = new byte[153600];
                }

                writer.close();
                reader.close();

            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }

        } 
        catch (MalformedURLException e) 
        {
            e.printStackTrace();
        }
    }
}

所有内容如DownloadButton.setEnabled(false);以及下面的几行都会在下载完所有文件后更改,有人会说我为什么会这样做吗?

1 个答案:

答案 0 :(得分:5)

如果从事件处理程序调用此方法,则在事件调度线程中执行,并且下载块重新绘制和事件处理。另一方面,GUI的更新只能从事件派发线程完成。见http://docs.oracle.com/javase/tutorial/uiswing/concurrency/

最简单的解决方法是为下载启动一个新线程,如下所示。为了更好地与GUI集成,例如在下载完成时更新它,请参阅教程。

private void updateContent()
{
    DownloadButton.setEnabled(false);
    SaveLocationButton.setEnabled(false);
    UpdateText.setText("Update to Version " + ServerVersionNumber + "...");
    UpdateText.setForeground(new Color(200, 150, 0, 255));
    ProgressText.setText("(1/2) Files will be downloaded");
    ProgressText.setForeground(new Color(200, 150, 0, 255));
    LoadingBar.setStringPainted(true);

    new Thread() {
        public void run() {
            for(int i = 1; i < (ServerVersionNumber - LocalVersionNumber + 1); i++)
            {
                // the rest
            }
        }
    }.start();
}