Use generic to prevent duplicate code in this case
You can take the common code in the functions in DictionaryScanner out into a common method:

    public boolean didAllRescanTasksFinish() {
        didAllXTasksFinish(rescanTasks);
    }

    private boolean didAllXTasksFinish(List&lt;AbstractWorkerTask&gt; tasks) {
        for (final AbstractWorkerTask task : tasks) {
            if (task.isWorking()) {
                return false;
            }
        }
        return true;
    }


Otherwise your second block of code is about as simple as you can get, because each listener has different content. If you try to remove the boilerplate you will find it gets much more difficult to understand.