- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的主屏幕 UI 上有一个进度指示器,由各种选项卡和服务共享。每个 TabController 都有自己的服务实例。在我的 MainController 类中,对于每个选项卡,我已将每个服务的进度属性绑定(bind)到 ProgressIndicator。
@FXML
Region veil;
@FXML
ProgressIndicator progressDial;
progressDial.progressProperty().bind(tabController.commandService.progressProperty());
veil.visibleProperty().bind(tabController.commandService.runningProperty());
progressDial.visibleProperty().bind(tabController.commandService.runningProperty());
tabController.commandService.messageProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> ov, String t, String newValue) {
addCommentary(newValue);
}
});
但是我看到第一个服务使用后,后面的服务或任务的执行没有出现进度盘。我想知道我是否滥用了 ProgressIndicator,因为每个服务可能同时运行。我猜第一次完成后进度没有重置。我该如何重置它?progress property是只读的。
ReadOnlyDoubleProperty progressProperty() Gets the ReadOnlyDoubleProperty representing the progress.
并且调用 updateProgress(0) 不会使表盘重新出现。
我尝试使用 ProgressIndicator 作为全局变量来显式重置它
mainController.progressDial.setProgress(0);
但是失败了
java.lang.RuntimeException:无法设置绑定(bind)值。
在 javafx.beans.property.DoublePropertyBase.set(DoublePropertyBase.java:159)
我可能错了,但我认为这是 JavaFX UI 控件设计中的错误。将进度更新为 0 应该会重置进度指示器。
最佳答案
我的回答中有一些文字,因为从您的问题中我不太清楚您的实例出了什么问题。希望答案中的解释或示例代码有用。
I could be mistaken, but I think this is a fault in the JavaFX UI controls design. Updating progress to 0 should reset the progress Indicator.
你有点误会了。您已将指标的进度绑定(bind)到任务的进度。任务已完成,进度为 1。现在,如果您想将同一指标重新用于另一项任务或让它衡量其他事情的进度,您必须首先停止它衡量原始任务的进度。要取消与原始任务的进度指示器的关联,unbind这是进步。一旦进度指示器的进度不再绑定(bind)到原始任务的进度,您就可以自由地将指示器设置为您想要的任何值,或将其绑定(bind)到其他内容。
类似地,您一次只能将进度指示器的进度绑定(bind)到一件事(除非您双向绑定(bind)指示器,这不能用于任务进度,因为任务进度是只读的并且双向绑定(bind)到无论如何,多个任务进度值都是不正确的,因为每个任务都处于不同的进度点)。
make the dial reappear.
根据您的描述,我不确定为什么表盘首先会消失,因此需要重新出现。通常,当进度指示器的进度达到 1 时,它仍然保持可见,报告完全完成的进度,它不会自动消失。您可能将指示器的可见性设置为 false 或将其不透明度修改为零。这两个属性都与指标测量的实际进度无关。或者您可能正在从显示的场景中删除指示器。如果您在任务完成后修改可见性并将指示器设置为不可见,并且您希望随后再次看到它以衡量另一个任务的进度,那么您需要确保它在场景中,不透明度 > 0 并且可见性设置为 true。
一个建议
您只能运行一次任务,因此在完成后,如果它已经取得了一些进展,则将其进度设置回零没有多大意义。
属性类型
A progress indicator's progress property是一个普通的 DoubleProperty
,而不是 ReadOnlyDoubleProperty
,因此它可以直接设置(只要它没有绑定(bind)到另一个值)。
A task's progress property这是只读的,必须通过 updateProgress 更改.任务的进度属性可能已设置为只读,以便可以通过 updateProgress
例程中的特殊代码确保对它的更新是线程安全的。
示例代码
考虑以下代码(我相信)可以实现您正在尝试执行的操作的意图。该代码模拟了铁人三项赛的运行,其中铁人三项赛的每个阶段(游泳、自行车、运行)都是一项单独的任务。在进行铁人三项时,进度指示器会显示铁人三项每个阶段的进度。当铁人三项比赛完成时,进度指示器会逐渐消失,直到开始新的铁人三项比赛。抱歉,示例太长了,我发现很难想出更简洁的内容。
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.beans.*;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.concurrent.Task;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Triathlon extends Application {
private final Random random = new Random();
private final ExecutorService exec = Executors.newSingleThreadExecutor();
@Override public void start(Stage stage) throws Exception {
final TaskMonitor taskMonitor = new TaskMonitor();
final ProgressIndicator progressIndicator = new ProgressIndicator();
progressIndicator.progressProperty().bind(
taskMonitor.currentTaskProgressProperty()
);
final Label currentRaceStage = new Label();
currentRaceStage.textProperty().bind(
taskMonitor.currentTaskNameProperty()
);
createMainLayout(
stage,
createStartRaceButton(
exec,
taskMonitor
),
createRaceProgressView(
taskMonitor,
progressIndicator,
currentRaceStage
)
);
}
@Override public void stop() throws Exception {
exec.shutdownNow();
}
private Button createStartRaceButton(final ExecutorService exec, final TaskMonitor taskMonitor) {
final Button startButton = new Button("Start Race");
startButton.disableProperty().bind(taskMonitor.idleProperty().not());
startButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
runRace(exec, taskMonitor);
}
});
return startButton;
}
private HBox createRaceProgressView(final TaskMonitor taskMonitor, ProgressIndicator progressIndicator, Label currentRaceStage) {
final HBox raceProgress = new HBox(10);
raceProgress.getChildren().setAll(
currentRaceStage,
progressIndicator
);
raceProgress.setOpacity(0);
raceProgress.setAlignment(Pos.CENTER);
final FadeTransition fade = new FadeTransition(Duration.seconds(0.75), raceProgress);
fade.setToValue(0);
taskMonitor.idleProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
if (taskMonitor.idleProperty().get()) {
fade.playFromStart();
} else {
fade.stop();
raceProgress.setOpacity(1);
}
}
});
return raceProgress;
}
private void createMainLayout(Stage stage, Button startButton, HBox raceProgress) {
final VBox layout = new VBox(10);
layout.getChildren().setAll(
raceProgress,
startButton
);
layout.setAlignment(Pos.CENTER);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10px;");
stage.setScene(new Scene(layout, 200, 130));
stage.show();
}
private void runRace(ExecutorService exec, TaskMonitor taskMonitor) {
StageTask swimTask = new StageTask("Swim", 30, 40);
StageTask bikeTask = new StageTask("Bike", 210, 230);
StageTask runTask = new StageTask("Run", 120, 140);
taskMonitor.monitor(swimTask, bikeTask, runTask);
exec.execute(swimTask);
exec.execute(bikeTask);
exec.execute(runTask);
}
class TaskMonitor {
final private ReadOnlyObjectWrapper<StageTask> currentTask = new ReadOnlyObjectWrapper<>();
final private ReadOnlyStringWrapper currentTaskName = new ReadOnlyStringWrapper();
final private ReadOnlyDoubleWrapper currentTaskProgress = new ReadOnlyDoubleWrapper();
final private ReadOnlyBooleanWrapper idle = new ReadOnlyBooleanWrapper(true);
public void monitor(final StageTask task) {
task.stateProperty().addListener(new ChangeListener<Task.State>() {
@Override
public void changed(ObservableValue<? extends Task.State> observableValue, Task.State oldState, Task.State state) {
switch (state) {
case RUNNING:
currentTask.set(task);
currentTaskProgress.unbind();
currentTaskProgress.set(task.progressProperty().get());
currentTaskProgress.bind(task.progressProperty());
currentTaskName.set(task.nameProperty().get());
idle.set(false);
break;
case SUCCEEDED:
case CANCELLED:
case FAILED:
task.stateProperty().removeListener(this);
idle.set(true);
break;
}
}
});
}
public void monitor(final StageTask... tasks) {
for (StageTask task: tasks) {
monitor(task);
}
}
public ReadOnlyObjectProperty<StageTask> currentTaskProperty() {
return currentTask.getReadOnlyProperty();
}
public ReadOnlyStringProperty currentTaskNameProperty() {
return currentTaskName.getReadOnlyProperty();
}
public ReadOnlyDoubleProperty currentTaskProgressProperty() {
return currentTaskProgress.getReadOnlyProperty();
}
public ReadOnlyBooleanProperty idleProperty() {
return idle.getReadOnlyProperty();
}
}
class StageTask extends Task<Duration> {
final private ReadOnlyStringWrapper name;
final private int minMinutesElapsed;
final private int maxMinutesElapsed;
public StageTask(String name, int minMinutesElapsed, int maxMinutesElapsed) {
this.name = new ReadOnlyStringWrapper(name);
this.minMinutesElapsed = minMinutesElapsed;
this.maxMinutesElapsed = maxMinutesElapsed;
}
@Override protected Duration call() throws Exception {
Duration duration = timeInRange(
minMinutesElapsed, maxMinutesElapsed
);
for (int i = 0; i < 25; i++) {
updateProgress(i, 25);
Thread.sleep((int) (duration.toMinutes()));
}
updateProgress(25, 25);
return duration;
}
private Duration timeInRange(int min, int max) {
return Duration.minutes(
random.nextDouble() * (max - min) + min
);
}
public ReadOnlyStringProperty nameProperty() {
return name.getReadOnlyProperty();
}
}
public static void main(String[] args) {
Application.launch(Triathlon.class);
}
}
其他问题的更新
Instead of being a triathlon, suppose each stage was instead, an independent event (like in the Olympics). So swim, bike, run etc. are instances of SportService. They execute concurrently. On the stadium electronic scoreboard is a progress indicator dial that is shared by all SportServices swim, bike, run etc. It gives me the approximate general progress - though I realize that is vague but is a summary of how everything is progressing without seeing the details of each event.
使用 Creating multiple parallel tasks 中定义的机制并行运行事件.为您的整体奥运会进度创建一个进度指示器,并使用低级绑定(bind) api 将其绑定(bind)到所有任务的进度总和的进度。
ObservableList<Service> services = FXCollections.observableArrayList();
. . . add services to list.
// extract the progress property for each of the added services.
final ReadOnlyDoubleProperty[] taskProgressList = new ReadOnlyDoubleProperty[services.size()];
for (int i = 0; i < taskProgressList.length; i++) {
taskProgressList[i] = services.get(i).progressProperty();
}
// calculate the average progress of all services.
DoubleBinding overallProgress = Bindings.createDoubleBinding(new Callable<Double>() {
@Override public Double call() throws Exception {
double value = 0;
for (int i = 0; i < taskProgressList.length; i++) {
value += taskProgressList[i].get();
}
value /= taskProgressList.length;
return value;
}
}, taskProgressList);
// bind the overall progress to our indicator
ProgressIndicator overallProgressIndicator = new ProgressIndicator();
overallProgressIndicator.progressProperty().bind(overallProgress);
这是另一个演示如何使用 overallProgress DoubleBinding
的示例。
import java.io.*;
import java.net.URL;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.*;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class FirstLineSequentialVsParallelService extends Application {
private static final String[] URLs = {
"http://www.google.com",
"http://www.yahoo.com",
"http://www.microsoft.com",
"http://www.oracle.com"
};
private ExecutorService sequentialFirstLineExecutor;
private ExecutorService parallelFirstLineExecutor;
@Override public void init() throws Exception {
sequentialFirstLineExecutor = Executors.newFixedThreadPool(
1,
new FirstLineThreadFactory("sequential")
);
parallelFirstLineExecutor = Executors.newFixedThreadPool(
URLs.length,
new FirstLineThreadFactory("parallel")
);
}
@Override
public void stop() throws Exception {
parallelFirstLineExecutor.shutdown();
parallelFirstLineExecutor.awaitTermination(3, TimeUnit.SECONDS);
sequentialFirstLineExecutor.shutdown();
sequentialFirstLineExecutor.awaitTermination(3, TimeUnit.SECONDS);
}
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) throws Exception {
final VBox messages = new VBox();
messages.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
messages.getChildren().addAll(
new Label("Parallel Execution"),
new Label("------------------")
);
DoubleBinding parallelProgress = fetchFirstLines(messages, parallelFirstLineExecutor);
ProgressMonitoredLabel parallelProgressSummary = new ProgressMonitoredLabel("Parallel Execution Summary");
parallelProgressSummary.progress.progressProperty().bind(parallelProgress);
messages.getChildren().add(parallelProgressSummary);
messages.getChildren().addAll(
new Label("Sequential Execution"),
new Label("--------------------")
);
DoubleBinding sequentialProgress = fetchFirstLines(messages, sequentialFirstLineExecutor);
ProgressMonitoredLabel sequentialProgressSummary = new ProgressMonitoredLabel("Sequential Execution Summary");
sequentialProgressSummary.progress.progressProperty().bind(sequentialProgress);
messages.getChildren().add(sequentialProgressSummary);
messages.setStyle("-fx-font-family: monospace;");
stage.setScene(new Scene(messages, 600, 650));
stage.show();
}
private DoubleBinding fetchFirstLines(final VBox monitoredLabels, ExecutorService executorService) {
ObservableList<Service> services = FXCollections.observableArrayList();
for (final String url: URLs) {
final FirstLineService service = new FirstLineService();
service.setExecutor(executorService);
service.setUrl(url);
final ProgressMonitoredLabel monitoredLabel = new ProgressMonitoredLabel(url);
monitoredLabels.getChildren().add(monitoredLabel);
monitoredLabel.progress.progressProperty().bind(service.progressProperty());
service.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override public void handle(WorkerStateEvent t) {
monitoredLabel.addStrings(
service.getMessage(),
service.getValue()
);
}
});
service.start();
services.add(service);
}
final ReadOnlyDoubleProperty[] taskProgressList = new ReadOnlyDoubleProperty[services.size()];
for (int i = 0; i < taskProgressList.length; i++) {
taskProgressList[i] = services.get(i).progressProperty();
}
return Bindings.createDoubleBinding(new Callable<Double>() {
@Override public Double call() throws Exception {
double value = 0;
for (int i = 0; i < taskProgressList.length; i++) {
value += taskProgressList[i].get();
}
value /= taskProgressList.length;
return value;
}
}, taskProgressList);
}
public class ProgressMonitoredLabel extends HBox {
final ProgressBar progress;
final VBox labels;
public ProgressMonitoredLabel(String initialString) {
super(20);
progress = new ProgressBar();
labels = new VBox();
labels.getChildren().addAll(new Label(initialString), new Label());
progress.setPrefWidth(100);
progress.setMinWidth(ProgressBar.USE_PREF_SIZE);
HBox.setHgrow(labels, Priority.ALWAYS);
setMinHeight(60);
getChildren().addAll(progress, labels);
}
public void addStrings(String... strings) {
for (String string: strings) {
labels.getChildren().add(
labels.getChildren().size() - 1,
new Label(string)
);
}
}
}
public static class FirstLineService extends Service<String> {
private StringProperty url = new SimpleStringProperty(this, "url");
public final void setUrl(String value) { url.set(value); }
public final String getUrl() { return url.get(); }
public final StringProperty urlProperty() { return url; }
protected Task createTask() {
final String _url = getUrl();
return new Task<String>() {
{ updateProgress(0, 100); }
protected String call() throws Exception {
updateMessage("Called on thread: " + Thread.currentThread().getName());
URL u = new URL(_url);
BufferedReader in = new BufferedReader(
new InputStreamReader(u.openStream()));
String result = in.readLine();
in.close();
// pause just so that it really takes some time to run the task
// so that parallel execution behaviour can be observed.
for (int i = 0; i < 100; i++) {
updateProgress(i, 100);
Thread.sleep(50);
}
return result;
}
};
}
}
static class FirstLineThreadFactory implements ThreadFactory {
static final AtomicInteger poolNumber = new AtomicInteger(1);
private final String type;
public FirstLineThreadFactory(String type) {
this.type = type;
}
@Override public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable, "LineService-" + poolNumber.getAndIncrement() + "-thread-" + type);
thread.setDaemon(true);
return thread;
}
}
}
关于javafx-2 - 如何重置 JavaFX2 中任务之间的进度指示器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16368793/
我不知道这是不是问这种问题的最佳地点, 我看到一些 JavaFX伙计们,重新标记 一些问题通过替换 javafx来自 javafx-2并采用新的 javafx-8 .它被弃用了还是什么? 编辑 : 不
错误本身: Error:java: invalid flag: --add-modules=javafx.fxml,javafx.graphics,javafx.controls,javafx.bas
这个想法是让一个应用程序在每个显示器上显示两个不同的窗口(阶段),该应用程序应该知道计算机有多少个显示器及其分辨率。 javafx有可能吗? 最佳答案 对于当前版本的 JavaFX (2.2),您可以
我正在将我的项目从 javafx 1.3 转换为 javafx 2.1。但我对 javafx.lang 有疑问包裹。 最佳答案 JavaFX 1.3 lang 包内容被拆分并移至下一个位置: 时长变为
当我尝试将标签添加到 gridpane 中时,如第二张图片所示,它不起作用。我已经尝试了很多东西,比如添加 CSS,但它仍然无法正常工作。为什么第 113 和 114 行不起作用? (opcje.se
我有一个JavaFX ContextMenu分配给滚动面板的鼠标右键单击。它会打开,但在滚动 Pane 外部单击时不会关闭。我可以在滚动 Pane 中添加另一个鼠标事件以将其隐藏,但这只能解决1个问题
我有一个tableview,其中附有一个可观察到的自定义类对象的列表(类类型:SalesInvoiceNetSale)。该表中的所有数据都可以正常显示。可观察列表中的最后一项是总计行(类类型:Sale
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 2年前关闭。 Improve this questi
我想知道如何在JavaFX中绘制半圆。我尝试使用Shape和QuadCurve,但无法制作出完美的半圆。 这是我要绘制的图片: 最佳答案 您链接的图片实际上是一个半圆环。您可以通过绘制嵌套的2条圆弧和
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在寻找 JavaFX 支持的图像类型(最新)列表,例如PNG、JPEG、TIFF。不同的搜索引擎没有帮助......知道从哪里开始吗? 更特别的是,我对 16 位灰度图像(不同格式)和罕见的受支持
我希望在 javafx 中让标签每 0.1 秒闪烁一次。文本显示在后台运行的 ImageView gif 的顶部。我将如何去做,或者您对最佳方法有什么建议? 谢谢 最佳答案 @fabian 的解决方案
我需要测试所选项目的值以调用不同的方法,因此我编写了添加侦听器的代码,但是该代码生成语法错误 @FXML private JFXComboBox cmbComp; cmbComp.valuePrope
我正在 Javafx 中编写一个非常简单的应用程序,其中舞台上有一个带有文本框的按钮作为一个场景。现在,我想要的行为是,当我单击按钮时,我可以使用另一个按钮加载另一个场景和舞台上的一个文本框,然后删除
编辑:如果用户单击“删除”以删除 ListView 中的项目,我会弹出一个警告框。它有效,但我希望它能超越原来的舞台。它出现在我的第一台显示器上。有什么方法可以设置警报显示时的位置吗? 请注意,“所有
我想使用 JavaFX 编写一个笔画绘图应用程序。我有一个压敏绘图板,如果能够读取笔的压力和倾斜值,那就太好了。 JavaFX 有一个 API 可以处理鼠标、触摸和滑动输入,但似乎没有任何东西可以产生
我在 JavaFX 中使用条形图和折线图。当我使两个图表大小相同并将它们放在同一位置时,它们完美地相互重叠。我如何使折线图显示在条形图的顶部。 目前我已将它们的不透明度设置为 0.7,这样它们“看起来
此问题与 this 相关。现在我想为字段值等于某个值的行着色。 @FXML private TableView tv_mm_view; @FXML private Ta
我有一个程序,可以生成高度图(0-255 的整数的 2D 数组),并使用 Shape3D“Box”对象为每个“像素”构建 3D View ,其高度与其在高度图中的值成比例。这会创建一个看起来很酷的四四
我想为 JavaFX 创建上下文菜单。这是我测试过的代码。但是由于某种原因,当我右键单击树节点时没有上下文菜单。你能帮我找出我的错误吗。 import java.util.Arrays; import
我是一名优秀的程序员,十分优秀!