public WorkflowStepController() {

    try {
      FXUtilities.injectFXML(this);
    } catch (IOException ex) {
      ImageJFX.getLogger().log(Level.SEVERE, null, ex);
    }
  }
/** @author Tuan anh TRINH */
@ViewController(value = "ProcessWorkflow.fxml")
public class ProcessWorkflow extends CorrectionFlow {

  @Inject WorkflowModel workflowModel;

  @Parameter DisplayService displayService;
  @Parameter ImageDisplayService imageDisplayService;

  @Parameter DatasetUtillsService datasetUtillsService;

  @Parameter LoadingScreenService loadingScreenService;

  @Parameter Context context;

  @Parameter IOService iOService;

  @FXML ListView<File> listViewItems;

  @FXML Button processButton;

  @FXML HBox hBox;

  @FXML GridPane gridPane;

  private File directory;

  ImageDisplayPane imageDisplayPaneLeft;

  ImageDisplayPane imageDisplayPaneRight;

  ExecutorService executor = ImageJFX.getThreadPool();

  public ProcessWorkflow() {
    CorrectionActivity.getStaticContext().inject(this);

    try {
      imageDisplayPaneLeft = new ImageDisplayPane(context);
      imageDisplayPaneRight = new ImageDisplayPane(context);
    } catch (IOException ex) {
      Logger.getLogger(ProcessWorkflow.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  @PostConstruct
  public void init() {
    bindListView();
    setCellFactory(listViewItems);
    gridPane.add(imageDisplayPaneLeft, 1, 1);
    gridPane.add(imageDisplayPaneRight, 2, 1);
    ImageDisplayPane[] imageDisplayPanes =
        new ImageDisplayPane[] {imageDisplayPaneLeft, imageDisplayPaneRight};
    bindPaneProperty(Arrays.asList(imageDisplayPanes));

    processButton.setOnMouseClicked(
        e -> {
          saveDirectory();
          if (directory != null) {
            process();
          }
        });
  }

  /** Compute the dataset */
  public void process() {
    List<File> files = workflowModel.getFiles();
    listViewItems.getItems().clear();
    workflowModel.getMapImages().clear();
    System.gc();
    workflowModel
        .transformeImages(files, directory.getAbsolutePath())
        .thenRunnable(
            () -> {
              files.sort(
                  (File o1, File o2) -> {
                    return o1.getName().compareTo(o2.getName());
                  });
              listViewItems.getItems().addAll(files);
            })
        .start();
  }

  /** Add the items and set the listener on change */
  public void bindListView() {
    listViewItems.getItems().addAll(workflowModel.getMapImages().keySet());
    listViewItems
        .getSelectionModel()
        .selectedItemProperty()
        .addListener(
            (ObservableValue<? extends File> observable, File oldValue, File newValue) -> {
              createSampleImage(newValue).start();
            });
  }

  /**
   * @param imageDisplay
   * @param firstPosition
   * @param secondPosition
   * @param imageDisplayPane
   */
  public void selectPosition(
      ImageDisplay imageDisplay,
      long[] firstPosition,
      long[] secondPosition,
      ImageDisplayPane imageDisplayPane) {
    workflowModel.setPosition(firstPosition, imageDisplay);
    imageDisplayService.getActiveDatasetView(imageDisplay).setColorMode(ColorMode.COLOR);
    Dataset datasetFirstSlide = datasetUtillsService.extractPlane(imageDisplay);
    workflowModel.setPosition(secondPosition, imageDisplay);
    Dataset datasetSecondSlide = datasetUtillsService.extractPlane(imageDisplay);
    workflowModel.extractAndMerge(
        new Dataset[] {datasetFirstSlide, datasetSecondSlide}, imageDisplayPane);
  }

  /**
   * Extract the plane at the different positions and concatenate the Dataset
   *
   * @param newValue
   * @return
   */
  private CallbackTask<Void, Void> createSampleImage(File newValue) {
    return new CallbackTask<Void, Void>()
        .run(
            () -> {
              try {
                File fileTarget = workflowModel.getMapImages().get(newValue);
                Dataset datasetTarget = (Dataset) iOService.open(fileTarget.getAbsolutePath());
                ImageDisplay imageDisplayTarget = new SilentImageDisplay();
                context.inject(imageDisplayTarget);
                imageDisplayTarget.display(datasetTarget);
                selectPosition(
                    imageDisplayTarget,
                    workflowModel.getPositionLeft(),
                    workflowModel.getPositionRight(),
                    imageDisplayPaneRight);

                Dataset datasetSource = (Dataset) iOService.open(newValue.getAbsolutePath());
                ImageDisplay imageDisplaySource = new SilentImageDisplay();
                context.inject(imageDisplaySource);
                imageDisplaySource.display(datasetSource);
                selectPosition(
                    imageDisplaySource,
                    workflowModel.getPositionLeft(),
                    workflowModel.getPositionRight(),
                    imageDisplayPaneLeft);

              } catch (IOException ex) {
                Logger.getLogger(ProcessWorkflow.class.getName()).log(Level.SEVERE, null, ex);
              }
            })
        .submit(loadingScreenService);
  }

  @FXML
  public void saveDirectory() {
    directory = null;
    DirectoryChooser directoryChooser = new DirectoryChooser();
    File file = directoryChooser.showDialog(null);
    directory = file;
  }
}
 @Override
 protected void addSeparatorToTop(MenuBar t) {
   ImageJFX.getLogger().warning("A seperator should have been inserted but was not.");
 }