code: private SwingBackgroundTask<Sudoku> createTask(final String[] puzzle,
                                                     final int populationSize,
                                                     final int eliteCount)
      {
          return new SwingBackgroundTask<Sudoku>()
          {
              @Override
              protected Sudoku performTask()
              {
                  Random rng = new MersenneTwisterRNG();
                  List<EvolutionaryOperator<Sudoku>> operators = new ArrayList<EvolutionaryOperator<Sudoku>>(2);
                  // Cross-over rows between parents (so offspring is x rows from parent1 and
                  // y rows from parent2).
                  operators.add(new SudokuVerticalCrossover());
                  // Mutate the order of cells within individual rows.
                  operators.add(new SudokuRowMutation(new PoissonGenerator(2, rng),
                                                      new DiscreteUniformGenerator(1, 8, rng)));
  
                  EvolutionaryOperator<Sudoku> pipeline = new EvolutionPipeline<Sudoku>(operators);
  
                  EvolutionEngine<Sudoku> engine = new GenerationalEvolutionEngine<Sudoku>(new SudokuFactory(puzzle),
                                                                                           pipeline,
                                                                                           new SudokuEvaluator(),
                                                                                           selectionStrategy,
                                                                                           rng);
                  engine.addEvolutionObserver(new SwingEvolutionObserver<Sudoku>(new GridViewUpdater(),
                                                                                 100,
                                                                                 TimeUnit.MILLISECONDS));
                  engine.addEvolutionObserver(statusBar);
                  return engine.evolve(populationSize,
                                       eliteCount,
                                       new TargetFitness(0, false), // Continue until a perfect solution is found...
                                       abortControl.getTerminationCondition()); // ...or the user aborts.
              }
  
  
              @Override
              protected void postProcessing(Sudoku result)
              {
                  puzzleCombo.setEnabled(true);
                  populationSizeSpinner.setEnabled(true);
                  solveButton.setEnabled(true);
                  abortControl.getControl().setEnabled(false);
              }
          };
      }
docs: Helper method to create a background task for running the interactive evolutionary
  algorithm.
  @return A Swing task that will execute on a background thread and update
  the GUI when it is done.