Java GUI Threading - PullRequest
       2

Java GUI Threading

2 голосов
/ 21 декабря 2011

У меня есть программа с графическим интерфейсом, которая в этом примере загружает исполняемый файл, используя wget.У меня есть нить, которая загружает файл.Есть статическая переменная, содержащая размер файла.Затем у меня есть цикл while, который проверяет фактический размер файла и обновляет JLabel, пока загрузка не будет завершена на 100%.Очевидно, что графический интерфейс не обновляется, и все останавливается до завершения потока, что для меня странно, так как я думал, что смысл создания этого потока - обойти эту проблему.Пожалуйста, дайте мне знать, что я сделал не так и что нужно изменить в теме.Я хочу, чтобы все было так просто, как сейчас.

К вашему сведению: у меня есть 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 очень хорошо.Спасибо!

1 Ответ

5 голосов
/ 21 декабря 2011

Когда обновится ярлык?Вы зацикливаетесь на нити диспетчеризации событий (EDT) - именно тогда Swing делает свою живопись.Ваш while цикл, а не тема загрузки, препятствует обновлению графического интерфейса.

Ответ прост: javax.swing.SwingWorker.Вот всеобъемлющее руководство SwingWorker от Oracle.

Также рассмотрите возможность использования JProgressBar вместо или вместе с JLabel.Для этого также есть учебное пособие: Как использовать индикаторы выполнения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...