[英]Java GUI Threading
我有一个GUI程序,在此示例中,该程序使用wget
下载一个exe。 我设置了一个下载文件的线程。 有一个静态变量保存文件的大小。 然后,我有一个while循环,检查实际文件大小并更新JLabel
直到下载完成100%。 GUI显然不会更新,并且一切都将暂停,直到线程完成为止,这对我来说很奇怪,因为我认为制作此线程的目的是绕过此问题。 请让我知道我做错了什么以及需要更改该线程的内容。 我想尝试使它保持当前的简单性。
仅供参考:我在那里有System.out.println()
,因此您可以看到它确实正确更新了当前文件大小。 另外,如果要下载的文件已经存在,则整个操作将无法进行(因为while循环立即变为true)。
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中复制过来。 谢谢!
标签何时更新? 您正在循环进入事件调度线程(EDT)-那是Swing进行绘制的时间。 您的while
循环while
不是下载线程正在阻止GUI更新。
答案很简单: javax.swing.SwingWorker
。 这是Oracle的综合SwingWorker教程 。
还可以考虑使用JProgressBar
代替JLabel
或与JLabel
一起使用。 也有一个教程: 如何使用进度条
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.