This section describes the progress monitor support.

Drombler FX provides out-of-the-box support for monitoring long-running Workers by integrating a ProgressMonitor in the Status Bar.

ProgressMonitor
Image 1: ProgressMonitor

[1] a label bound to Worker#titleProperty
[2] a label bound to Worker#messageProperty
[3] a progress bar bound to Worker#progressProperty
[4] a button to execute Worker#cancel
[5] an indicator if there are additional workers being monitored
[6] a popup showing all monitored workers

This feature is optional and must be activated if required.

1. Activation

To activate the progress monitor integration in the Status Bar you need the following additional runtime dependency in your application:

<dependency>
    <groupId>org.drombler.fx</groupId>
    <artifactId>drombler-fx-core-standard-status</artifactId>
    <scope>runtime</scope>
</dependency>
Make sure that the Status Bar is activated, too.

2. Notification

The progress monitor integration listens for any non-finished Worker instances in the application-wide context.

To notify the progress monitor about the availability of a new Worker instance, simply add it to the local context of a Dromber FX managed component:

public class WorkerProvider implements LocalContextProvider {

    private static final Logger LOG = LoggerFactory.getLogger(WorkerProvider.class);

    private final SimpleContextContent contextContent = new SimpleContextContent();
    private final SimpleContext context = new SimpleContext(contextContent);
    private final ExecutorService executorService
            = Executors.newCachedThreadPool(runnable -> {
                Thread thread = new Thread(runnable);
                thread.setDaemon(true);
                return thread;
            });

    public void runTask() {
        SampleTask sampleTask = new SampleTask();
        // ! add the task to the local context
        // the progress monitor will pick it up automatically
        sampleTask.setOnRunning(event -> contextContent.add(sampleTask));
        sampleTask.setOnSucceeded(event -> {
            Foo foo = sampleTask.getValue();
            // do something
        });
        sampleTask.setOnFailed(event -> {
            String errorMessage = "Sample task failed!";
            Throwable exception = sampleTask.getException();
            if (exception != null) {
                LOG.error(errorMessage, exception);
            } else {
                LOG.error(errorMessage);
            }
            // show error dialog
        });
        sampleTask.stateProperty().addListener((observable, oldValue, newValue) -> {
            // you can use org.drombler.commons.fx.concurrent.WorkerUtils
            // to easily check for finished states
            if (WorkerUtils.getFinishedStates().contains(newValue)) {
                // ! remove the task from the local context
                contextContent.remove(sampleTask);
            }
        });
        executorService.execute(sampleTask);
    }

    @Override
    public Context getLocalContext() {
        return context;
    }

The Context Framework allows a loose coupling between the progress monitor and other Drombler managed components.