我正在尝试展示每个任务的进度和状态。每个任务都在
对于"Progress"
但是我的JavaFX应用程序在连续使用后会冻结UI。有没有其他方法可以在后台线程中自动触发特定时间间隔后调用updateProgressbar(),并且不会冻结我的JavaFX应用程序的UI?
我不知道是否正确更新每个任务在单独线程中运行的任务状态。如果我想借助javafx.concurrent包来实现这一点,那么有人能给我一些指导或流程吗?任务将放入什么位置,服务类将放入什么位置?我如何安排它以更新进度条?FYI:一次只允许执行5个线程。
编辑 -
根据Andy Till先生的建议,我已经更新了我的代码,但仍然没有运气。
在 QueueData 类中 -
TableView
中以一行表示。每个任务在不同的Thread
中并行执行。请参考TableView
图像。对于"Progress"
TableColumn
,我已经设置了单元格工厂来呈现`ProgressBar"。 public static class ProgressBarTableCell<S, T> extends TableCell<S, T> {
private final ProgressBar progressBar;
private ObservableValue<T> ov;
public ProgressBarTableCell() {
this.progressBar = new ProgressBar();
progressBar.setPrefHeight(23);
setAlignment(Pos.CENTER);
}
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setGraphic(null);
setText(null);
} else {
if (item.toString().equalsIgnoreCase("Processing")) {
Platform.runLater(new Runnable() {
@Override
public void run() {
if (getGraphic() == null) {
setGraphic(progressBar);
progressBar.setProgress(-1);
} else {
ProgressBar objpProgressBar = (ProgressBar) getGraphic();
objpProgressBar.setProgress(-1);
}
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
});
} else {
Platform.runLater(new Runnable() {
@Override
public void run() {
if (getGraphic() == null) {
setGraphic(progressBar);
progressBar.setProgress(0);
} else {
ProgressBar objpProgressBar = (ProgressBar) getGraphic();
objpProgressBar.setProgress(0);
}
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
});
}
}
}
}
TableView
没有显示任务的最新状态和进度,所以我在后台定期运行一个线程,当我调用startUpdatingTableProgress()时,修改TableView
并停止运行时调用stopUpdatingTableProgress()。
public void stopUpdatingTableProgress() {
keepUpdating = false;
}
public void startUpdatingTableProgress() {
keepUpdating = true;
TableProgressBarUpdator tpu = new TableProgressBarUpdator(table);
tpu.start();
}
class TableProgressBarUpdator implements Runnable {
TableView table;
public TableProgressBarUpdator(TableView fxtable) {
table = fxtable;
}
public void start() {
new Thread(this).start();
}
public void run() {
while (keepUpdating) {
try {
updateProgressbar();
Thread.sleep(1000);
} catch (Exception e) {
LogHandler.doErrorLogging("Error while updating tables cell", e);
}
}
LogHandler.doDebugLogging("Table process repainting is completed.");
}
private void updateProgressbar() throws Exception {
Platform.runLater(new Runnable() {
@Override
public void run() {
((TableColumn) table.getColumns().get(0)).setVisible(false);
((TableColumn) table.getColumns().get(0)).setVisible(true);
}
});
}
}
但是我的JavaFX应用程序在连续使用后会冻结UI。有没有其他方法可以在后台线程中自动触发特定时间间隔后调用updateProgressbar(),并且不会冻结我的JavaFX应用程序的UI?
我不知道是否正确更新每个任务在单独线程中运行的任务状态。如果我想借助javafx.concurrent包来实现这一点,那么有人能给我一些指导或流程吗?任务将放入什么位置,服务类将放入什么位置?我如何安排它以更新进度条?FYI:一次只允许执行5个线程。
编辑 -
根据Andy Till先生的建议,我已经更新了我的代码,但仍然没有运气。
TableColumn tableColumn_Progress = new TableColumn("Progress");
tableColumn_Progress.setCellValueFactory(new PropertyValueFactory<QueueData, Double>("progressBar"));
tableColumn_Progress.setPrefWidth(100);
Callback<TableColumn<QueueData, Double>, TableCell<QueueData, Double>> attachmentCellFactory = //
new Callback<TableColumn<QueueData, Double>, TableCell<QueueData, Double>>() {
@Override
public TableCell call(final TableColumn param) {
final ProgressBarTableCell cell = new ProgressBarTableCell() {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
}
};
return cell;
}
};
tableColumn_Progress.setCellFactory(attachmentCellFactory);
在 QueueData 类中 -
DoubleProperty progressBar = null;
public DoubleProperty progressBarProperty() {
return progressBar;
}
public Double getprogressBar() {
return progressBar.get();
}
public void setprogressBar(Double sType) {
this.progressBar = new SimpleDoubleProperty(sType);
}
我尝试过不使用后台线程更新UI,但没有成功。