paintComponent не рисует, а приложение зависает

102
12 октября 2019, 20:40

Делаю Progressbar и paintComponent должен по чуть-чуть заполнять полосу. Написал следующие методы:

GetLastVersionButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent event) {
       Preferences user = Preferences.userRoot().node("Node");
       Updater updater = new Updater(user.get("FolderDirectory", null) + File.separator + "client.zip");
       updater.downloadClient();
   }
});

Далее получаем файл для скачки:

public void downloadClient() {
        try {
            url = new URL(Utils.getClientUrl());
            url.openConnection();
            inputStream = url.openStream();
            Preferences user = Preferences.userRoot().node("Node");
            folder = new File(user.get("FolderDirectory", null));
            if(!folder.exists()) folder.mkdirs();
            fileOutputStream = new FileOutputStream(outputFile);
            byte[] buf = new byte[1024];
            urlconnection = new URL(url.toString()).openConnection();
            urlconnection.setDefaultUseCaches(false);
            allB += urlconnection.getContentLength();
            logMsg("Скачивание клиента...");
            while ((b = inputStream.read(buf)) > 0) {
                fileOutputStream.write(buf, 0, b);
                buf = new byte[1024];
                downloadB += b;
                System.out.println(downloadB);
                Main.downloadProgressbar.setValue(downloadB, allB);
            }
            fileOutputStream.close();
            inputStream.close();
        } catch (Exception e){}
    }

Специально сделал System.out.println(downloadB);, чтоб видеть, что параметры для paintComponent всегда обновляются и таки да, циферки бегут, все как надо.

Если убрать while и отправить напрямую Main.downloadProgressbar.setValue(downloadB, allB); , то progressbar обновится 1 раз соответственно, с while же просто все падает.

Далее принимаю эти значения, тут также все цифры принимаются и обновляются:

public void setValue(int bytesDownload, int bytesTotal) {
        allB = bytesTotal;
        downloadB = bytesDownload;
        repaint();
    }

И вот собственно сам paintComponent:

protected void paintComponent(Graphics graphics) {
        try {
            Graphics2D g = (Graphics2D) graphics.create();
            Font font = new Font("Arial",Font.TRUETYPE_FONT ,16);
            String done = "Done!";
            double wProgressBarOnline = 434.0 / allB * downloadB;
            double allMB = new BigDecimal(allB * 0.000001).setScale(2, RoundingMode.UP).doubleValue();
            double downloadMB = new BigDecimal(downloadB * 0.000001).setScale(2, RoundingMode.UP).doubleValue();
            double centerXDone = (441.0 / 2) - g.getFontMetrics(font).stringWidth(done) / 2;
            double centerXProgress = (441.0 / 2) - g.getFontMetrics(font).stringWidth((float)downloadMB + "/" + (float)allMB + " MB") / 2;
            String progress = (float)downloadMB + "/" + (float)allMB + " MB";
            g.setFont(font);
            g.setColor(Color.black);
            progressBarBackground = progressBarOnline = check = ImageIO.read(ADownloadProgressbar.class.getResource("/My/Images/progressbar.png"));
            progressBarBackground = progressBarBackground.getSubimage(41, 29, 441,36);
            progressBarOnline = progressBarOnline.getSubimage(45, 0, (int)wProgressBarOnline + 1, 29);
            check = check.getSubimage(0, 29, 41, 36);
            g.drawImage(progressBarBackground, 0, 0, progressBarBackground.getWidth(), progressBarBackground.getHeight(), null);
            g.drawImage(progressBarOnline, 2, 3, progressBarOnline.getWidth(), progressBarOnline.getHeight(), null);
            g.drawString(progress, (int)centerXProgress, 25);

            g.dispose();
            super.paintComponent(graphics);
        } catch(Exception e){e.printStackTrace();}
    }

По итогу такая картина, что при клике по кнопке загрузка файла по факту идет, на компьютер все скачивается, но прогресс бар стоит мертвый + само приложение зависает. Не работают кнопки, окно нельзя передвинуть и т.д., хотя опять же повторюсь, скачивание идет не прерываясь, ошибок при отладки нет никаких.

Буду благодарен если поможете!

Answer 1

Дело в том, что все это вы делаете в одном потоке, и пока у вас весь процесс не закончится, ваша панель не перерисовывается. Попробуйте так

public void downloadClient() {
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    url = new URL(Utils.getClientUrl());
                    url.openConnection();
                    inputStream = url.openStream();
                    Preferences user = Preferences.userRoot().node("Node");
                    folder = new File(user.get("FolderDirectory", null));
                    if (!folder.exists()) folder.mkdirs();
                    fileOutputStream = new FileOutputStream(outputFile);
                    byte[] buf = new byte[1024];
                    urlconnection = new URL(url.toString()).openConnection();
                    urlconnection.setDefaultUseCaches(false);
                    allB += urlconnection.getContentLength();
                    logMsg("Скачивание клиента...");
                    while ((b = inputStream.read(buf)) > 0) {
                        fileOutputStream.write(buf, 0, b);
                        buf = new byte[1024];
                        downloadB += b;
                        System.out.println(downloadB);
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                Main.downloadProgressbar.setValue(downloadB, allB);
                            }
                        });
                    }
                    fileOutputStream.close();
                    inputStream.close();
                } catch (Exception e) {
                }
            }
        }).start();
    }

Можно подойти по другому и запустить процесс скачивания в SwingWorker - это более правильный вариант.

READ ALSO
Отступ в Navigation Menu

Отступ в Navigation Menu

Возможно ли добавить divider со своим цветом в 5dp или Bottom margin в 5dp для итемов Navigation меню?

121
Как исправить проблему в modal-backdrop fade show

Как исправить проблему в modal-backdrop fade show

Проблема такая: http://inkomtradeooo/novosti

134
Как сверстать такой input radio?

Как сверстать такой input radio?

Как получить такой input radio на css ?

144