Вот схема, которая только что пришла мне в голову:
interface WorkProcess
void setWorkUnits(int units)
void setArguments(Object obj1,...)
void execute()
Таким образом, вы инкапсулируете все свои задачи с интерфейсом, который выполняет execute
согласно классическому шаблону команд;также сказано (см. ниже), сколько работы, вероятно, займет эта работа.Вы, вероятно, захотите, чтобы какой-то механизм передавал данные в эти задачи, чтобы они могли работать с ними.
class WorkProcessFactory
static WorkProcess makeWorkProcess()
static int getTotalWorkUnitsAllocated()
static synchronized int reportWorkDone(int units)
static void addProgressListener(ProgressListener xxx)
Когда у вас есть работа, вы просите фабрику изготовить для вас один из этих процессов.При этом он выполняет оценку рабочих единиц и передает ее в только что созданный рабочий процесс.Он также ведет подсчет общего количества этих юнитов для настройки верхней части индикатора прогресса.Одним из приятных побочных эффектов этого является то, что вам не нужно ждать, пока все ваши задания будут подготовлены: вы можете увеличивать максимальное значение для своего отчета о ходе работы каждый раз, когда добавляете работу, даже когда работы обрабатываются и создаются заново;ваш бар всегда будет отображать реалистичное соотношение.
Вы можете поместить свои рабочие процессы в какую-то очередь.ExecutorService
приходит на ум, если ваш WorkProcess также реализует интерфейс Runnable
(что является хорошей идеей).Вы сможете обрабатывать эти задания последовательно по одному файлу или одновременно - независимо от того, что поддерживает механизм очереди выполнения.
Метод WorkProcess 'execute()
в основном обертывает метод run()
(или, возможно, другой способ).вокруг, так как ExecutorService ожидает метод run (), но наша магия рабочих единиц находится в execute()
);но когда это сделано, он добросовестно перезванивает на reportWorkDone
с тем количеством единиц, которое ему сказали, что его работа того стоила.После получения этих отчетов у фабрики есть обновленное значение для единиц выполненной работы, о котором оно может сообщить обратно отслеживающему ProgressListener.Это, в свою очередь, обновляет панель в графическом интерфейсе.
Готово.(Я думаю).Вероятно, нуждается в доработке.