简体   繁体   中英

Java GUI Threading

I have a GUI program that, in this example, downloads an exe using wget . 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. 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. 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. Also, the entire thing won't work if the file being downloaded already exists (since the while loop is instantly 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. Thanks!

When will the label update? You're looping in the Event Dispatch Thread (EDT) - that's when Swing does its painting. Your while loop, not the download thread, is preventing the GUI from updating.

The answer is simple: javax.swing.SwingWorker . Here is a comprehensive SwingWorker tutorial from Oracle.

Also consider using a JProgressBar instead of or along with a JLabel . There's a tutorial for that too: How to Use Progress Bars

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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