有没有办法在JavaFX应用程序中获取所有正在运行的任务和服务?
我想在列表中显示正在运行的任务。
答案 0 :(得分:4)
MonitoringExecutor.java:
import java.util.concurrent.Executor;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
/**
* Wraps an Executor and exposes an ObservableList of Workers which have been
* executed but have not completed. (Workers are considered completed if they
* exit a RUNNING state; i.e. they are in a SUCCEEDED, FAILED, or CANCELLED state.)
*
*/
public class MonitoringExecutor implements Executor {
private final Executor exec ;
private final ObservableList<Worker<?>> taskList ;
public MonitoringExecutor(Executor exec) {
this.exec = exec;
this.taskList = FXCollections.observableArrayList();
}
@Override
public void execute(Runnable command) {
if (command instanceof Worker) {
final Worker<?> task = (Worker<?>) command ;
task.stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> obs,
State oldState, State newState) {
if (oldState == State.RUNNING) {
taskList.remove(task);
}
}
});
taskList.add(task);
}
exec.execute(command);
}
public ObservableList<Worker<?>> getWorkerList() {
return taskList;
}
}
以下是使用它的一个例子:
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TaskMonitor extends Application {
@Override
public void start(Stage primaryStage) {
final IntegerProperty tasksCreated = new SimpleIntegerProperty(0);
final ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
};
final MonitoringExecutor exec = new MonitoringExecutor(Executors.newFixedThreadPool(5, threadFactory));
final TableView<Worker<?>> taskTable = createTable();
taskTable.setItems(exec.getWorkerList());
final Button newTaskButton = new Button();
newTaskButton.textProperty().bind(Bindings.format("Create task %d", tasksCreated.add(1)));
newTaskButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
tasksCreated.set(tasksCreated.get()+1);
exec.execute(new CountingTask("Task "+tasksCreated.get()));
}
});
final BorderPane root = new BorderPane();
root.setCenter(taskTable);
final HBox controls = new HBox();
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
controls.getChildren().add(newTaskButton);
root.setBottom(controls);
final Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private TableView<Worker<?>> createTable() {
final TableView<Worker<?>> taskTable = new TableView<>();
final TableColumn<Worker<?>, String> titleCol = new TableColumn<>("Title");
titleCol.setCellValueFactory(new PropertyValueFactory<Worker<?>, String>("title"));
final TableColumn<Worker<?>, Double> progressCol = new TableColumn<>("Progress");
progressCol.setCellValueFactory(new PropertyValueFactory<Worker<?>, Double>("progress"));
progressCol.setCellFactory(new Callback<TableColumn<Worker<?>, Double>, TableCell<Worker<?>, Double>>() {
@Override
public TableCell<Worker<?>, Double> call(TableColumn<Worker<?>, Double> col) {
return new ProgressTabelCell();
}
});
final TableColumn<Worker<?>, State> stateCol = new TableColumn<>("State");
stateCol.setCellValueFactory(new PropertyValueFactory<Worker<?>, State>("state"));
final TableColumn<Worker<?>, String> messageCol = new TableColumn<>("Message");
messageCol.setCellValueFactory(new PropertyValueFactory<Worker<?>, String>("message"));
messageCol.setPrefWidth(200);
taskTable.getColumns().addAll(Arrays.asList(titleCol, progressCol, stateCol, messageCol));
return taskTable;
}
private static class CountingTask extends Task<Void> {
private CountingTask(String title) {
updateTitle(title);
}
@Override
protected Void call() throws Exception {
final int n = new Random().nextInt(100)+100;
for (int i=0; i<n; i++) {
updateProgress(i, n);
updateMessage(String.format("Count is %d (of %d)", i, n));
Thread.sleep(100);
}
return null;
}
}
private static class ProgressTabelCell extends TableCell<Worker<?>, Double> {
final ProgressBar progressBar = new ProgressBar();
@Override
public void updateItem(Double value, boolean empty) {
if (empty || value == null) {
setGraphic(null);
} else {
setGraphic(progressBar);
progressBar.setProgress(value);
}
}
}
public static void main(String[] args) {
launch(args);
}
}
答案 1 :(得分:2)
只需根据需要在列表中添加和删除它们即可。然后你可以在列表中显示它们。这是一些代码。
ObservableList<String> runningTasks;
runningTasks.add(task.getTitle());
new Thread(task).start();
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent event) {
runningTasks.remove(task.getTitle());
}});