Java GUI线程

时间:2011-12-21 03:16:32

标签: java multithreading swing user-interface

我有一个GUI程序,在本例中,使用wget下载exe。我有一个线程设置下载文件。有一个静态变量保存文件的大小。然后我有一个while循环检查实际文件大小并更新JLabel,直到下载完成100%。 GUI显然没有更新,一切都停止,直到线程完成,这对我来说很奇怪,因为我认为制作这个线程的目的是绕过这个问题。请让我知道我做错了什么,以及需要更改线程的内容。我想尽量保持这个目前的简单。

仅供参考:我有System.out.println(),因此您可以看到它正确更新了当前文件大小。此外,如果正在下载的文件已经存在(因为while循环立即生效),整个过程将无法工作。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class downloaderProgram implements ActionListener {
    JFrame frame;
    JPanel p1, p2, p3;
    JButton start;
    JLabel status;

    downloaderProgram() {
        frame = new JFrame("Downloader");
        frame.setSize(500, 400);

        //p1
        p1 = new JPanel();

        //p2
        p2 = new JPanel();

        status  = new JLabel("");
        p2.add(status);

        //p3
        GridLayout p3Grid = new GridLayout(0, 1);
        p3 = new JPanel();
        p3.setLayout(p3Grid);

        start = new JButton("Start");
        start.setMargin(new Insets(10,0,10,0));

        p3.add(start);

        //frame
        frame.add(p1, BorderLayout.NORTH);
        frame.add(p2, BorderLayout.CENTER);
        frame.add(p3, BorderLayout.SOUTH);

        start.addActionListener(this);

        //output.setEditable(false);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(start)) {
            long fileSize = 1110476;

            downloadThread dt = new downloadThread();
            dt.start();

            long length = 0;
            File download = new File("7z920.exe");
            while (length != fileSize) {
                length = download.length();
                status.setText(Long.toString(length));
                System.out.println(Long.toString(length));
            }

            start.setEnabled(false);
        }
    }

    public static void main(String[] args) {
        new downloaderProgram();
    }
}
class downloadThread extends Thread {
    public void run() {
        try {
            String cmd = "wget http://downloads.sourceforge.net/sevenzip/7z920.exe";
            Runtime run = Runtime.getRuntime();
            Process pr = run.exec(cmd);
        } catch(IOException io) {
            System.out.println(io);
        }
    }
}

很抱歉,如果间距有点混乱 - 它没有很好地从我的IDE复制。谢谢!

1 个答案:

答案 0 :(得分:5)

标签何时更新?你在事件调度线程(EDT)中循环 - 当Swing进行绘画时。您的while循环,而不是下载线程,阻止了GUI的更新。

答案很简单:javax.swing.SwingWorker。这是来自Oracle的comprehensive SwingWorker tutorial

另请考虑使用JProgressBar代替JLabel或与{{1}}一起使用{{1}}。还有一个教程:How to Use Progress Bars