我环顾四周,找不到任何体面的片段,告诉你如何创建准确的进度条。通过使用Thread.sleep(10)
来指示执行“工作”的线程上的一些工作负载,我见过的所有这些都是廉价的黑客攻击。在某些情况下,这是非常不准确的,因为它实际上没有考虑线程工作负载。我也不想使用不确定的进度条,因为那些看起来很糟糕。
我的问题是:如何创建一个准确的进度条(非不确定),该线程与执行所有“工作”的线程并行运行,在这种情况下将数千个图像写入目录。如果您不知道线程的工作负载,并且您不知道实际转储所有这些线程需要多长时间。解决这个问题的最佳方法是什么?我试图让这个变得现实,而不是仅为化妆品显示进度条。
所以,假设我有一个这样的程序。
@FXML
private void dump(ActionEvent e) {
try {
if (e.getSource() == spriteDumpMI) {
Thread thread = new Thread(() -> {
try (Cache cache = new Cache(FileStore.open(Constants.CACHE_PATH))) {
ReferenceTable table = ReferenceTable.decode(Container
.decode(cache.getStore().read(255, 8)).getData());
Platform.runLater(() -> {
createTask(10, table.capacity());
});
for (int i = 0; i < table.capacity(); i++) {
if (table.getEntry(i) == null)
continue;
Container container = cache.read(8, i);
Sprite sprite = Sprite.decode(container.getData());
File dir = new File(Constants.SPRITE_PATH);
if (!dir.exists()) {
dir.mkdir();
}
for (int frame = 0; frame < sprite.size(); frame++) {
File file = new File(Constants.SPRITE_PATH,
i + "_" + frame + ".png");
BufferedImage image = sprite.getFrame(frame);
ImageIO.write(image, "png", file);
}
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
});
thread.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
程序很简单,基本上它会写入存档中的所有精灵(可以是几千张图像)并将所有精灵写入目录,以便用户可以使用它们。
我正在使用此更新我的进度条。
Platform.runLater(() -> {
// this is bad
createTask(10, table.capacity());
});
我知道我可以更新循环中的进度条,但是我不知道如何在不创建大量线程和新任务的情况下做到这一点(这也非常糟糕)
方法createTask
private void createTask(int workload, int max) {
Task<Boolean> task = taskCreator(workload, max);
progressBar.setVisible(true);
progressI.setVisible(true);
progressBar.progressProperty().unbind();
progressBar.progressProperty().bind(task.progressProperty());
progressI.progressProperty().unbind();
progressI.progressProperty().bind(task.progressProperty());
new Thread(task).start();
}
private Task<Boolean> taskCreator(int workload, int max) {
return new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
progressText.setText("In Progress");
progressText.setFill(Color.WHITE);
for (int index = 0; index < max; index++) {
Thread.sleep(workload);
updateProgress(index, max);
}
progressText.setText("Complete!");
progressText.setFill(Color.GREEN);
Thread.sleep(1000);
progressBar.setVisible(false);
progressI.setVisible(false);
progressText.setText("");
return true;
}
};
}
答案 0 :(得分:0)
希望这可以提供帮助。
@FXML
private void dump(ActionEvent e) {
try {
if (e.getSource() == spriteDumpMI) {
progressBar.setVisible(true);
progressI.setVisible(true);
progressBar.progressProperty().unbind();
progressBar.progressProperty().bind(task.progressProperty());
progressI.progressProperty().unbind();
progressI.progressProperty().bind(task.progressProperty());
progressText.textProperty().unbind();
progressText.textProperty().bind(task.messageProperty());
progressText.setFill(Color.GREEN);
Task task = new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
updateMessage("In Progress");
try (Cache cache = new Cache(FileStore.open(Constants.CACHE_PATH))) {
ReferenceTable table = ReferenceTable.decode(Container
.decode(cache.getStore().read(255, 8)).getData());
long count;
for (int i = 0; i < table.capacity(); i++) {
if (table.getEntry(i) == null)
continue;
Container container = cache.read(8, i);
Sprite sprite = Sprite.decode(container.getData());
File dir = new File(Constants.SPRITE_PATH);
if (!dir.exists()) {
dir.mkdir();
}
for (int frame = 0; frame < sprite.size(); frame++) {
count++;
}
}
int current;
for (int i = 0; i < table.capacity(); i++) {
if (table.getEntry(i) == null)
continue;
Container container = cache.read(8, i);
Sprite sprite = Sprite.decode(container.getData());
File dir = new File(Constants.SPRITE_PATH);
if (!dir.exists()) {
dir.mkdir();
}
for (int frame = 0; frame < sprite.size(); frame++) {
File file = new File(Constants.SPRITE_PATH,
i + "_" + frame + ".png");
BufferedImage image = sprite.getFrame(frame);
ImageIO.write(image, "png", file);
current++;
updateProgress(current, count);
}
}
updateMessage("Complete!");
Platform.runLater(() -> {
progressText.setFill(Color.GREEN);
});
} catch (FileNotFoundException e1) {
e1.printStackTrace();
updateMessage("failed!");
Platform.runLater(() -> {
progressText.setFill(Color.GREEN);
});
} catch (IOException e1) {
e1.printStackTrace();
updateMessage("failed!");
Platform.runLater(() -> {
progressText.setFill(Color.GREEN);
});
}
return true;
}
};
}
task.setOnSucceeded(e ->{
progressBar.setVisible(false);
progressI.setVisible(false);
progressText.setText("");
});
task.setOnFailed(e ->{
progressBar.setVisible(false);
progressI.setVisible(false);
progressText.setText("");
});
new Thread(task).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}