简体   繁体   English

Java GUI线程

[英]Java GUI Threading

I have a GUI program that, in this example, downloads an exe using wget . 我有一个GUI程序,在此示例中,该程序使用wget下载一个exe。 I have a thread set up that downloads the file. 我设置了一个下载文件的线程。 There is a static variable holding the file's size. 有一个静态变量保存文件的大小。 Then I have a while loop that checks the actual file size and updates a JLabel until the download is 100% complete. 然后,我有一个while循环,检查实际文件大小并更新JLabel直到下载完成100%。 The GUI obviously isn't updating and everything is halted until the thread completes, which to me is odd since I thought the point of making this thread would be to bypass this problem. GUI显然不会更新,并且一切都将暂停,直到线程完成为止,这对我来说很奇怪,因为我认为制作此线程的目的是绕过此问题。 Please let me know what I've done wrong and what about the thread needs to be changed. 请让我知道我做错了什么以及需要更改该线程的内容。 I want to try and keep this as simple as it is currently. 我想尝试使它保持当前的简单性。

FYI: I have the System.out.println() in there so you can see that it does properly update the current file size. 仅供参考:我在那里有System.out.println() ,因此您可以看到它确实正确更新了当前文件大小。 Also, the entire thing won't work if the file being downloaded already exists (since the while loop is instantly true). 另外,如果要下载的文件已经存在,则整个操作将无法进行(因为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);
        }
    }
}

Sorry if the spacing is a bit messed up--it didn't copy over from my IDE very well. 抱歉,如果间距有些混乱,它不能很好地从我的IDE中复制过来。 Thanks! 谢谢!

When will the label update? 标签何时更新? You're looping in the Event Dispatch Thread (EDT) - that's when Swing does its painting. 您正在循环进入事件调度线程(EDT)-那是Swing进行绘制的时间。 Your while loop, not the download thread, is preventing the GUI from updating. 您的while循环while不是下载线程正在阻止GUI更新。

The answer is simple: javax.swing.SwingWorker . 答案很简单: javax.swing.SwingWorker Here is a comprehensive SwingWorker tutorial from Oracle. 这是Oracle的综合SwingWorker教程

Also consider using a JProgressBar instead of or along with a JLabel . 还可以考虑使用JProgressBar代替JLabel或与JLabel一起使用。 There's a tutorial for that too: How to Use Progress Bars 也有一个教程: 如何使用进度条

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM