我正在制作一个 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();}
}
结果,这样的图片,当你点击按钮时,文件实际上是下载的,所有的东西都下载到了电脑上,但是进度条是死的+应用程序本身冻结了。按钮不起作用,窗口无法移动等,虽然我再说一遍,下载没有中断,调试过程中没有错误。
如果您能提供帮助,我将不胜感激!
事实是您在一个线程中完成所有这些,并且在完成整个过程之前,您的面板不会重绘。像这样试试
您可以以不同的方式处理它并在SwingWorker中启动下载过程- 这是一个更正确的选择。