RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 946389
Accepted
Slam
Slam
Asked:2020-02-19 02:18:11 +0000 UTC2020-02-19 02:18:11 +0000 UTC 2020-02-19 02:18:11 +0000 UTC

paintComponent 不绘制并且应用程序冻结

  • 772

我正在制作一个 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);,那么进度条会分别更新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();}
    }

结果,这样的图片,当你点击按钮时,文件实际上是下载的,所有的东西都下载到了电脑上,但是进度条是死的+应用程序本身冻结了。按钮不起作用,窗口无法移动等,虽然我再说一遍,下载没有中断,调试过程中没有错误。

如果您能提供帮助,我将不胜感激!

java
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Z.John
    2020-02-19T02:26:51Z2020-02-19T02:26:51Z

    事实是您在一个线程中完成所有这些,并且在完成整个过程之前,您的面板不会重绘。像这样试试

    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中启动下载过程- 这是一个更正确的选择。

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5