问题描述
我一直在寻找一些关于如何创建多个任务并让它们一个接一个地运行的时间。这是java代码:
I've been searching for some time now on how to create multiple tasks and have them run one after the other. Here is the java code:
public class Main extends Application {
DropShadow shadow = new DropShadow();
Button button = new Button("Start");
Task<Integer> task;
Task<Integer> task2;
Label label1 = new Label("Status: NOT STARTED");
ProgressBar bar = new ProgressBar(0);
ProgressIndicator pi = new ProgressIndicator(0);
Thread th = new Thread();
public void start(Stage stage) {
task = new Task<Integer>() {
protected Integer call() throws Exception {
int iterations;
for (iterations = 0; iterations < 1001; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateProgress(iterations, 1001);
updateMessage("Test");
try {
Thread.sleep(10);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
//updateMessage("Cancelled");
break;
}
}
}
return iterations;
}
};
task2 = new Task<Integer>() {
protected Integer call() throws Exception {
int iterations;
for (iterations = 0; iterations < 1001; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateProgress(iterations, 1001);
updateMessage("Test");
try {
Thread.sleep(10);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
//updateMessage("Cancelled");
break;
}
}
}
return iterations;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
public void handle(WorkerStateEvent arg0) {
label1.setText("Done");
new Thread(task2).start();
}
});
Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Progress Controls");
final Slider slider = new Slider();
slider.setMin(0);
slider.setMax(50);
bar.progressProperty().bind(task.progressProperty());
pi.progressProperty().bind(task.progressProperty());
label1.textProperty().bind(task.messageProperty());
button.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
button.setEffect(shadow);
new Thread(task).start();
}
});
button.addEventHandler(MouseEvent.MOUSE_RELEASED, new EventHandler <MouseEvent>() {
public void handle(MouseEvent arg0) {
button.setEffect(null);
}
});
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(bar, pi, button, label1);
scene.setRoot(hb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
基本上我想要两个进度条和大约5个总共任务。一个进度条将用于当前任务运行,另一个进度条用于整体进度。一旦task1完成,我希望它运行任务2并将进度条更新回零,同时增加其他进度。但是,一旦我为其他任务创建了一个新线程,GUI中的任何内容都不会更新。
Basically I want to have two progress bars and around 5 tasks in total. One progress bar will be for the current task running and the other one for the overall progress. Once task1 is done, I want it to run task 2 and update the progress bar back to zero while increasing the other progress one. However, once I create a new Thread for the other task nothing in the GUI gets updated.
提前致谢。
编辑:
我修复了开始的部分代码第二项任务。但是,我有以下问题:
I have fixed the part of the code that starts the second task. However, I have these questions:
-
如何创建一个在不同任务完成后更新的整体进度条?
How can I create an overall progress bar that gets updated as different tasks get completed?
每个新任务启动后,如何为每个单独的任务动态重置和更新单个进度条?我是否必须为此创建各种ProgressBar对象?
How can I dynamically reset and update the single progress bar for each individual task once each new task is launched? Do I have to create various ProgressBar objects for this?
推荐答案
您的解决方案作品。这是边缘的,但我建议有一个解决方案,其中task1不知道task2。你可以这样做:
Your solution works. It's marginal, but I would suggest it's slightly better to have a solution where task1 doesn't know about task2. You can do this by:
- 使用onSucceeded处理程序重新绑定进度条
- 使用单线程执行程序并向其提交任务
对于整体进度,您可以创建一个代表总数的DoubleBinding进展。
For the "overall progress", you could create a DoubleBinding that represents the total progress.
public class Main extends Application {
DropShadow shadow = new DropShadow();
Button button = new Button("Start");
Task<Integer> task;
Task<Integer> task2;
Label label1 = new Label("Status: NOT STARTED");
ProgressBar bar = new ProgressBar(0);
ProgressIndicator pi = new ProgressIndicator(0);
Thread th = new Thread();
public void start(Stage stage) {
task = new Task<Integer>() {
protected Integer call() throws Exception {
int iterations;
for (iterations = 0; iterations < 1001; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateProgress(iterations, 1001);
updateMessage("Test");
try {
Thread.sleep(10);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
//updateMessage("Cancelled");
break;
}
}
}
return iterations;
}
};
task2 = new Task<Integer>() {
protected Integer call() throws Exception {
int iterations;
for (iterations = 0; iterations < 1001; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateProgress(iterations, 1001);
updateMessage("Test");
try {
Thread.sleep(10);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
//updateMessage("Cancelled");
break;
}
}
}
return iterations;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
public void handle(WorkerStateEvent arg0) {
label1.setText("Done");
bar.progressProperty().unbind();
bar.progressProperty().bind(task2.progressProperty());
}
});
final int numTasks = 2 ;
DoubleBinding totalProgress = Bindings.createDoubleBinding(new Callable<Double>() {
@Override
public Double call() {
return ( Math.max(0, task1.getProgress())
+ Math.max(0, task2.getProgress()) ) / numTasks ;
},
task1.progressProperty(), task2.progressProperty());
pi.progressProperty().bind(totalProgress);
Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Progress Controls");
final Slider slider = new Slider();
slider.setMin(0);
slider.setMax(50);
bar.progressProperty().bind(task.progressProperty());
// pi.progressProperty().bind(task.progressProperty());
label1.textProperty().bind(task.messageProperty());
final ExecutorService exec = Executors.newSingleThreadExecutor();
button.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
button.setEffect(shadow);
exec.submit(task);
exec.submit(task2);
}
});
button.addEventHandler(MouseEvent.MOUSE_RELEASED, new EventHandler <MouseEvent>() {
public void handle(MouseEvent arg0) {
button.setEffect(null);
}
});
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(bar, pi, button, label1);
scene.setRoot(hb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
这篇关于多任务JavaFX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!