diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java b/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java index 267530c10293dc85544162291ccd146143ac1f85..a9ffc5368d89071f2371dbb4a7c061b844bebeb0 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java @@ -71,7 +71,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme private final static Logger LOGGER = LoggerFactory.getLogger( MainController.class ); private final SimpleObjectProperty< Dataset > currentDataset = new SimpleObjectProperty<>(); - private final SimpleObjectProperty< ClassifiedImages< FloatType > > images = new SimpleObjectProperty<>(); + //private final SimpleObjectProperty< ClassifiedImages< FloatType > > images = new SimpleObjectProperty<>(); private final SimpleObjectProperty< Img< FloatType > > pretreatedImg = new SimpleObjectProperty<>(); private final SimpleBooleanProperty disableGUI = new SimpleBooleanProperty(); private final SimpleBooleanProperty changedParameters = new SimpleBooleanProperty(); @@ -83,7 +83,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme @FXML - private PreprocessingController< T > preprocessingController; + private PreprocessingController preprocessingController; @FXML private SelectionController< T > selectionController; @FXML @@ -114,7 +114,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme model = new MainModel<>( preprocessingController.getModel(), selectionController.getModel(), constructionController.getConstructionModel(), projectionController.getModel() ); - + selectionController.setParent(this); @@ -140,32 +140,42 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme currentDataset.addListener( ( observableValue, dataset, t1 ) -> { - if ( t1 != null ) - { - selectionController.disableParameters(); - disableGUI.setValue( true ); - runPretreatment( currentDataset.getValue() ); - } - else + if (t1 == null) { pretreatedImg.setValue( null ); LOGGER.debug( "PRETREATED_IMAGE is NULL" ); } +// if ( t1 != null ) +// { +// selectionController.disableParameters(); +// disableGUI.setValue( true ); +// preprocessingController.runPreprocessing( ); +// } +// else +// { +// pretreatedImg.setValue( null ); +// LOGGER.debug( "PRETREATED_IMAGE is NULL" ); +// } } ); - pretreatedImg.addListener( ( observable, oldValue, newValue ) -> - { - if ( newValue != null ) - { - computeClassifiedImages(); - } - else - { - images.setValue( null ); - LOGGER.debug( "IMAGES is NULL" ); - } - } ); +// pretreatedImg.addListener( ( observable, oldValue, newValue ) -> +// { +// if ( newValue == null ) +// { +// images.setValue( null ); +// LOGGER.debug( "IMAGES is NULL" ); +// } +//// if ( newValue != null ) +//// { +//// computeClassifiedImages(); +//// } +//// else +//// { +//// images.setValue( null ); +//// LOGGER.debug( "IMAGES is NULL" ); +//// } +// } ); disableGUI.addListener( ( observable, oldValue, newValue ) -> runButton.setDisable( newValue ) ); @@ -181,9 +191,9 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme /* Binding properties*/ preprocessingController.getModel().currentDatasetProperty().bind( currentDataset ); - preprocessingController.getModel().pretreatedImgProperty().bind( pretreatedImg ); + preprocessingController.getModel().pretreatedImgProperty().bindBidirectional( pretreatedImg ); selectionController.getModel().pretreatedImgProperty().bind( pretreatedImg ); - selectionController.getModel().imagesProperty().bind( images ); + //selectionController.getModel().imagesProperty().bind( images ); constructionController.getConstructionModel().maximumsProperty().bind( selectionController.getModel().selectedPixelsProperty() ); projectionController.getModel().referenceSurfacesProperty().bind( constructionController.getConstructionModel().referenceSurfacesProperty() ); changedParameters.bindBidirectional( selectionController.changedParametersProperty() ); @@ -250,18 +260,13 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme LOGGER.debug( "###########################################---NEW RUN---###########################################" ); } - private void runPreprocessing( Dataset dataset ) - { - // AbstractTask< Img<T> > task = new BinningTask<>( pr ) - } - - private void runPretreatment( Dataset dataset ) - { - AbstractTask< Img< FloatType > > task = new PreprocessingTask<>( dataset, 2, 2 );//TODO default value to change - task.setOnSucceeded( workerStateEvent -> - pretreatedImg.setValue( task.getValue() ) ); - task.start(); - } +// private void runPretreatment( Dataset dataset ) +// { +// AbstractTask< Img< FloatType > > task = new PreprocessingTask<>( dataset, 2, 2 ); //TODO default value to change +// task.setOnSucceeded( workerStateEvent -> +// pretreatedImg.setValue( task.getValue() ) ); +// task.start(); +// } public void setAndDisplayDatasetChoices() { @@ -273,7 +278,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme list.add( null ); activeDatasets.setItems( list ); - LOGGER.debug( "item selected : list size = " + list.size() ); + LOGGER.debug( "item selected : list size = {}" , list.size() ); if ( list.isEmpty() ) { currentDataset.setValue( null ); @@ -294,12 +299,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme } - public void computeClassifiedImages() - { - ComputeClassificationImagesTask classifiedImagesTask = new ComputeClassificationImagesTask( pretreatedImg.getValue() ); - classifiedImagesTask.setOnSucceeded( workerStateEvent -> images.set( classifiedImagesTask.getValue() ) ); - classifiedImagesTask.start(); - } + public void setMainApp( MainAppFrame mainAppFrame ) { @@ -410,5 +410,34 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme } return true; } + +// public static void setNextOutputToNull( SimpleObjectProperty<?> property, SimpleObjectProperty<?> nextOutput) +// { +// property.addListener( ( observable, oldValue, newValue ) -> +// { +// if (newValue != oldValue && newValue != null) +// { +// LOGGER.debug( "The output {} is set to null.", nextOutput.getName()); +// nextOutput.set( null ); +// } +// }); +// } +// +// public static void resetResultFromParameter( SimpleObjectProperty<?> result, Control parameter) +// { +// result.addListener( ( observable, oldValue, newValue ) -> +// { +// if (newValue != oldValue && newValue != null) +// { +// LOGGER.debug( "The output {} is set to null due to parameter update.", result.getName()); +// result.set( null ); +// } +// }); +// } + + public PreprocessingController getPreprocessingController() + { + return preprocessingController; + } } diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/controller/PreprocessingController.java b/src/main/java/fr/pasteur/ida/zellige/gui/controller/PreprocessingController.java index 78f3212bede7ca12b262e889d914ed48ae1d2cc4..442ae78bea75a3697aedadf7bde2168c27e5483d 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/controller/PreprocessingController.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/controller/PreprocessingController.java @@ -1,22 +1,16 @@ package fr.pasteur.ida.zellige.gui.controller; import fr.pasteur.ida.zellige.gui.PreprocessingPanel; -import fr.pasteur.ida.zellige.gui.exception.NoA3DStackException; -import fr.pasteur.ida.zellige.gui.exception.NoInputException; -import fr.pasteur.ida.zellige.gui.exception.TimeLapseException; import fr.pasteur.ida.zellige.gui.model.PreprocessingModel; -import fr.pasteur.ida.zellige.gui.task.DisplayDatasetChoicesTask; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; +import fr.pasteur.ida.zellige.gui.task.AbstractTask; +import fr.pasteur.ida.zellige.gui.task.PreprocessingTask; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; -import javafx.scene.control.ComboBox; import javafx.scene.control.Spinner; import javafx.scene.control.SpinnerValueFactory; -import net.imagej.Dataset; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.RealType; +import net.imglib2.img.Img; +import net.imglib2.type.numeric.real.FloatType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,7 +19,7 @@ import java.util.ResourceBundle; -public class PreprocessingController < T extends RealType< T > & NativeType< T > > implements Initializable +public class PreprocessingController implements Initializable { private final static Logger LOGGER = LoggerFactory.getLogger( PreprocessingController.class ); @@ -42,7 +36,6 @@ public class PreprocessingController < T extends RealType< T > & NativeType< T > "fr.pasteur.ida.zellige.gui.view/PreprocessingPanel.fxml" ) ); fxmlLoader.setRoot( this ); fxmlLoader.setController( this ); - } @@ -53,18 +46,29 @@ public class PreprocessingController < T extends RealType< T > & NativeType< T > model = new PreprocessingModel(); //link Model with View - model.binProperty().bind(bin.valueProperty()); // link between model and controller + /* Control of the bin Spinner*/ SpinnerValueFactory< Integer > valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory( 1, 10, 1 ); bin.setValueFactory( valueFactory ); - bin.valueProperty().addListener( ( observableValue, number, newValue ) -> - model.runPreprocessingTask()); +// bin.valueProperty().addListener( ( observableValue, number, newValue ) -> +// runPreprocessing()); + model.binProperty().bind( bin.getValueFactory().valueProperty()); // link between model and controller } + public void runPreprocessing() + { + AbstractTask< Img< FloatType > > task = new PreprocessingTask<>(model.getCurrentDataset(), 2, model.getBin() ); + task.setOnSucceeded( workerStateEvent -> + model.pretreatedImgProperty().set( task.getValue() )); + + task.start(); + } + + public PreprocessingModel getModel() { return model; diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java b/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java index a00d308a8a3dc5fedb80a11fc10315d0f959c16f..07e1acc0ea91fb6032391812f66077a5fdbc420b 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java @@ -28,16 +28,20 @@ */ package fr.pasteur.ida.zellige.gui.controller; +import fr.pasteur.ida.zellige.gui.ParameterSlider; import fr.pasteur.ida.zellige.gui.ParameterSliderInteger; import fr.pasteur.ida.zellige.gui.ZSlicesSlider; import fr.pasteur.ida.zellige.gui.model.SelectionModel; import fr.pasteur.ida.zellige.gui.parameter.ZelligeParameters; import fr.pasteur.ida.zellige.gui.task.*; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Control; import javafx.scene.image.ImageView; import javafx.scene.layout.FlowPane; import net.imglib2.img.Img; @@ -50,6 +54,8 @@ import org.slf4j.LoggerFactory; import java.net.URL; import java.util.ResourceBundle; + + public class SelectionController< T extends RealType< T > & NativeType< T > > implements Initializable { private final static Logger LOGGER = LoggerFactory.getLogger( SelectionController.class ); @@ -58,6 +64,7 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im private final SimpleBooleanProperty changedParameters = new SimpleBooleanProperty(); private final SimpleBooleanProperty disableGUI = new SimpleBooleanProperty(); private SelectionModel model; + private MainController<T> parentController; @FXML private ParameterSliderInteger amplitude; @@ -73,12 +80,16 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im private ParameterSliderInteger zBlur; @FXML private ZSlicesSlider zSlices; + @FXML + private Button pixelSelection; + @Override public void initialize( URL url, ResourceBundle resourceBundle ) { + // model - model = new SelectionModel(); + model = new SelectionModel( ); //link Model with View model.amplitudeProperty().bind( amplitude.sliderProperty() ); @@ -87,66 +98,106 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im model.xyBlurProperty().bind( xyBlur.sliderProperty() ); model.zBlurProperty().bind( zBlur.sliderProperty() ); model.disableGUIProperty().bindBidirectional( disableGUI ); + + /* JavaFx Components */ /* Amplitude slider initialization */ +// amplitude.sliderProperty().addListener( ( observableValue, number, newValue ) -> +// { +// if ( amplitude.hasChanged( newValue ) && model.selectedAmplitudeProperty().getValue() != null ) +// { +// disableGUI.setValue( true ); +// runAmplitudeTask(); +// changedParameters.setValue( true ); +// } +// } ); + // Set the linked output to null when the related parameter(s) is (are) changed. + resetResultFromParameter( model.selectedAmplitudeProperty(), amplitude); + resetResultFromParameter( model.selectedOtsuProperty(), otsu ); + resetResultFromParameter( model.islandSearchImageProperty(), island ); + resetResultFromParameter( model.selectedPixelsProperty(), zBlur ); + resetResultFromParameter( model.selectedPixelsProperty(), xyBlur ); amplitude.sliderProperty().addListener( ( observableValue, number, newValue ) -> { - if ( amplitude.hasChanged( newValue ) && model.selectedAmplitudeProperty().getValue() != null ) - { - disableGUI.setValue( true ); - runAmplitudeTask(); - changedParameters.setValue( true ); - } - } ); - - /* Otsu slider initialization */ - otsu.sliderProperty().addListener( ( observableValue, number, newValue ) -> - { - if ( otsu.hasChanged( newValue ) && model.selectedOtsuProperty().getValue() != null ) + if ( amplitude.hasChanged( newValue )) { - disableGUI.setValue( true ); - runOtsuTask(); - changedParameters.setValue( true ); + model.selectedAmplitudeProperty().set( null ); } - } ); + }); - island.getSlider().valueProperty().addListener( ( observableValue, number, t1 ) -> - { - if ( island.hasChanged( t1 ) ) - { - model.setIslandSearchImage( null ); - changedParameters.setValue( true ); - } - } ); - xyBlur.sliderProperty().addListener( ( observable, oldValue, newValue ) -> - { - if ( xyBlur.hasChanged( newValue ) ) - { - model.setSelectedPixels( null ); - changedParameters.setValue( true ); - } - } ); - zBlur.sliderProperty().addListener( ( observable, oldValue, newValue ) -> - { - if ( zBlur.hasChanged( newValue ) ) - { - model.setSelectedPixels( null ); - changedParameters.setValue( true ); - } - } ); + /* Otsu slider initialization */ +// otsu.sliderProperty().addListener( ( observableValue, number, newValue ) -> +// { +// if ( otsu.hasChanged( newValue ) && model.selectedOtsuProperty().getValue() != null ) +// { +// disableGUI.setValue( true ); +// runOtsuTask(); +// changedParameters.setValue( true ); +// } +// } ); + +// otsu.sliderProperty().addListener( ( observableValue, number, newValue ) -> +// { +// if ( otsu.hasChanged( newValue )) +// { +// model.selectedOtsuProperty().set( null ); +// } +// }); + +// island.getSlider().valueProperty().addListener( ( observableValue, number, t1 ) -> +// { +// if ( island.hasChanged( t1 ) ) +// { +// model.setIslandSearchImage( null ); +// changedParameters.setValue( true ); +// } +// } ); + +// island.sliderProperty().addListener( ( observableValue, number, newValue ) -> +// { +// if ( island.hasChanged( newValue )) +// { +// model.islandSearchImageProperty().set( null ); +// } +// }); + +// xyBlur.sliderProperty().addListener( ( observable, oldValue, newValue ) -> +// { +// if ( xyBlur.hasChanged( newValue ) ) +// { +// model.setSelectedPixels( null ); +// changedParameters.setValue( true ); +// } +// } ); +// zBlur.sliderProperty().addListener( ( observable, oldValue, newValue ) -> +// { +// if ( zBlur.hasChanged( newValue ) ) +// { +// model.setSelectedPixels( null ); +// changedParameters.setValue( true ); +// } +// } ); stack.setAlignment( Pos.CENTER ); // section Slider initialization - zSlices.getSlider().valueProperty().addListener( ( observableValue, number, newValue ) -> +// zSlices.getSlider().valueProperty().addListener( ( observableValue, number, newValue ) -> +// { +// int newZValue = newValue.intValue(); +// if ( zSlices.hasChanged( newZValue ) ) +// { +// refreshDisplay( newZValue ); +// } +// } ); + + pixelSelection.setOnAction( actionEvent -> { - int newZValue = newValue.intValue(); - if ( zSlices.hasChanged( newZValue ) ) - { - refreshDisplay( newZValue ); - } + disableGUI.setValue( true ); + changedParameters.setValue( false ); + runPixelSelection(); + //run2(); } ); /* Properties */ @@ -162,65 +213,137 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im enableParameters(); } } ); - model.imagesProperty().addListener( ( observableValue, classifiedImages, t1 ) -> + + /* Chain reaction : if one parameter value is changed the following outputs are reset. */ + setNextOutputToNull( model.pretreatedImgProperty(), model.imagesProperty()); + + setNextOutputToNull( model.imagesProperty(), model.selectedAmplitudeProperty()); + setNextOutputToNull( model.imagesProperty(), model.selectedOtsuProperty()); + + setNextOutputToNull( model.selectedAmplitudeProperty(), model.interClassifiedImageProperty() ); + setNextOutputToNull( model.selectedOtsuProperty(), model.interClassifiedImageProperty() ); + + setNextOutputToNull( model.interClassifiedImageProperty(), model.islandSearchImageProperty() ); + + + setNextOutputToNull( model.islandSearchImageProperty(), model.selectedPixelsProperty() ); + + setNextOutputToNull( model.selectedPixelsProperty(), model.imageViewsProperty() ); + + model.pretreatedImgProperty().addListener( ( observableValue, number, newValue ) -> { - if ( t1 != null ) + LOGGER.debug( "Pretreated image value update."); + if (newValue != null ) { - runAmplitudeTask(); - runOtsuTask(); + LOGGER.debug( " Update value is valid : starting computing classified images" ); + computeClassifiedImages(); } - else + if (model.pretreatedImgProperty().getValue() == null) { - LOGGER.debug( "IMAGES is NULL" ); - model.selectedAmplitudeProperty().setValue( null ); - model.selectedOtsuProperty().setValue( null ); - model.interClassifiedImageProperty().setValue( null ); + parentController.getPreprocessingController().runPreprocessing(); } - } ); - ChangeListener< Img< BitType > > listener = ( observableValue, bitTypeClassifiedImages, t1 ) -> + + model.imagesProperty().addListener( ( observableValue, number, newValue ) -> { - if ( model.selectedAmplitudeProperty().getValue() != null && model.selectedOtsuProperty().getValue() != null ) + if (newValue != null) { - runInterClassification(); - LOGGER.debug( "Inter classification" ); + runAmplitudeTask(); + runOtsuTask(); } - else + }); + + model.selectedAmplitudeProperty().addListener( ( observableValue, number, newValue ) -> + { + if ( newValue != null && model.selectedOtsuProperty().getValue() != null) { - LOGGER.debug( "SELECTED_AMPLITUDE or SELECTED_OTSU is NULL" ); - model.interClassifiedImageProperty().setValue( null ); + runInterClassification(); } + }); - }; - - model.selectedAmplitudeProperty().addListener( listener ); - model.selectedOtsuProperty().addListener( listener ); - + model.selectedOtsuProperty().addListener( ( observableValue, number, newValue ) -> + { + if ( newValue != null && model.selectedAmplitudeProperty().getValue() != null) + { + runInterClassification(); + } + }); - model.interClassifiedImageProperty().addListener( ( observable, oldValue, newValue ) -> + model.interClassifiedImageProperty().addListener( ( observableValue, number, newValue ) -> { - LOGGER.info( "Computing double classification..." ); if ( newValue != null ) { - computeImageFXDisplay(); + runIslandSearch(); } - model.islandSearchImageProperty().setValue( null ); - } ); + }); - model.islandSearchImageProperty().addListener( ( observableValue, bitTypes, t1 ) -> + model.islandSearchImageProperty().addListener( ( observableValue, number, newValue ) -> { - if ( t1 == null ) + if ( newValue != null ) { - LOGGER.debug( "ISLAND_SEARCH is NULL" ); - model.selectedPixelsProperty().setValue( null ); + runSmoothing(); } - else + }); + + model.selectedPixelsProperty().addListener( ( observableValue, number, newValue ) -> + { + if ( newValue != null ) { - runSmoothing(); + computeImageFXDisplay(); } - } ); + }); + +// ChangeListener< Img< BitType > > listener = ( observableValue, bitTypeClassifiedImages, t1 ) -> +// { +// if ( model.selectedAmplitudeProperty().getValue() != null && model.selectedOtsuProperty().getValue() != null ) +// { +// runInterClassification(); +// LOGGER.debug( "Inter classification" ); +// } +// else +// { +// LOGGER.debug( "SELECTED_AMPLITUDE or SELECTED_OTSU is NULL" ); +// model.interClassifiedImageProperty().setValue( null ); +// } +// +// }; + +// model.selectedAmplitudeProperty().addListener( listener ); +// model.selectedOtsuProperty().addListener( listener ); + + +// model.interClassifiedImageProperty().addListener( ( observable, oldValue, newValue ) -> +// { +// LOGGER.info( "Computing double classification..." ); +// if ( newValue != null ) +// { +// computeImageFXDisplay(); +// } +// model.islandSearchImageProperty().setValue( null ); +// } ); +// +// model.islandSearchImageProperty().addListener( ( observableValue, bitTypes, t1 ) -> +// { +// if ( t1 == null ) +// { +// LOGGER.debug( "ISLAND_SEARCH is NULL" ); +// model.selectedPixelsProperty().setValue( null ); +// } +// else +// { +// runSmoothing(); +// } +// } ); + } + public void computeClassifiedImages() + { + + ComputeClassificationImagesTask classifiedImagesTask = new ComputeClassificationImagesTask( model.pretreatedImgProperty().getValue() ); + classifiedImagesTask.setOnSucceeded( workerStateEvent -> model.imagesProperty().set( classifiedImagesTask.getValue() ) ); + classifiedImagesTask.start(); } + public void runAmplitudeTask() { AmplitudeThresholdingTask amplitudeTask = new AmplitudeThresholdingTask( model.imagesProperty().get().getAmplitudeImg(), model.amplitudeProperty().getValue().intValue() ); @@ -275,14 +398,31 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im public void runPixelSelection() { - if ( model.islandSearchImageProperty().getValue() == null ) + LOGGER.debug("Starting pixel selection."); + if ( model.pretreatedImgProperty().getValue() == null) + { + parentController.getPreprocessingController().runPreprocessing(); + //computeClassifiedImages(); + } + + else if ( model.selectedAmplitudeProperty().getValue() == null || model.selectedOtsuProperty().getValue() == null) + { + + if ( model.selectedAmplitudeProperty().getValue() == null ) + { + runAmplitudeTask(); + } + if ( model.selectedOtsuProperty().getValue() == null ) + { + runOtsuTask(); + } + } + else if( model.islandSearchImageProperty().getValue() == null ) { - LOGGER.debug( "Island search image is NULL" ); runIslandSearch(); } else if ( model.selectedPixelsProperty().getValue() == null ) { - LOGGER.debug( "Island search image is not NULL" ); runSmoothing(); } } @@ -405,4 +545,33 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im xyBlur.setValue( parameters.getXyBlur() ); zBlur.setValue( parameters.getzBlur() ); } + + public void setParent( MainController< T > mainController ) + { + parentController = mainController; + } + + public static void setNextOutputToNull( SimpleObjectProperty<?> property, SimpleObjectProperty<?> nextOutput) + { + property.addListener( ( observable, oldValue, newValue ) -> + { + if (newValue != oldValue && newValue == null) + { + LOGGER.debug( "Next output set to null...." ); + nextOutput.set( null ); + } + }); + } + + public static void resetResultFromParameter( SimpleObjectProperty<?> result, ParameterSlider parameter) + { + parameter.sliderProperty().addListener( ( observable, oldValue, newValue ) -> + { + if (parameter.hasChanged( newValue ) && newValue != null ) + { + LOGGER.debug( "The output {} is set to null due to parameter update.", result.getValue().getClass().getName() ); + result.set( null ); + } + }); + } } diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/model/PreprocessingModel.java b/src/main/java/fr/pasteur/ida/zellige/gui/model/PreprocessingModel.java index cd571811dc0058256fa3a0e2b6c4b75381a139c3..4d6f07808a9540529b4620c351ba6d5f879862d5 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/model/PreprocessingModel.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/model/PreprocessingModel.java @@ -1,7 +1,5 @@ package fr.pasteur.ida.zellige.gui.model; -import fr.pasteur.ida.zellige.gui.task.AbstractTask; -import fr.pasteur.ida.zellige.gui.task.PreprocessingTask; import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; @@ -24,18 +22,14 @@ public class PreprocessingModel this.bin = new SimpleIntegerProperty(); } - public void runBinningTask() - { - } - - public void runPreprocessingTask() - { - AbstractTask< Img< FloatType > > task = new PreprocessingTask<>(currentDataset.get(), 2, getBin() ); - task.setOnSucceeded( workerStateEvent -> - pretreatedImg.setValue( task.getValue() ) ); - task.start(); - } +// public void runPreprocessingTask() +// { +// AbstractTask< Img< FloatType > > task = new PreprocessingTask<>(currentDataset.get(), 2, getBin() ); +// task.setOnSucceeded( workerStateEvent -> +// pretreatedImg.setValue( task.getValue() ) ); +// task.start(); +// } public int getBin() { @@ -57,6 +51,8 @@ public class PreprocessingModel return pretreatedImg.get(); } + + public SimpleObjectProperty< Img< FloatType > > pretreatedImgProperty() { return pretreatedImg; diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java b/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java index 7a7b4284c3e28a07095843fa6850fea9c7936e7e..973fd4b2bf7aa48d6e5dd4ff4272f8a4ed09e45e 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java @@ -60,6 +60,9 @@ public class SelectionModel private final SimpleObjectProperty< Pixels[][] > selectedPixels = new SimpleObjectProperty<>(); private final SimpleObjectProperty< ImageView[] > imageViews = new SimpleObjectProperty<>(); + + + public SelectionModel() { amplitude = new SimpleDoubleProperty(); diff --git a/src/main/resources/fr.pasteur.ida.zellige.gui.view/Selection.fxml b/src/main/resources/fr.pasteur.ida.zellige.gui.view/Selection.fxml index 08e23d88d8158eb75380a12fda16204f4cac4b9b..1de5281a9aaf86f113a54ada084812c8e4103e32 100644 --- a/src/main/resources/fr.pasteur.ida.zellige.gui.view/Selection.fxml +++ b/src/main/resources/fr.pasteur.ida.zellige.gui.view/Selection.fxml @@ -1,68 +1,58 @@ <?xml version="1.0" encoding="UTF-8"?> <!--suppress JavaFxDefaultTag --> -<?import fr.pasteur.ida.zellige.gui.*?> + +<?import fr.pasteur.ida.zellige.gui.ParameterSliderInteger?> +<?import fr.pasteur.ida.zellige.gui.StepPanel?> +<?import fr.pasteur.ida.zellige.gui.ZSlicesSlider?> <?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> <?import javafx.scene.control.Label?> -<?import javafx.scene.layout.*?> -<StepPanel xmlns:fx="http://javafx.com/fxml" maxHeight="-Infinity" maxWidth="-Infinity" - minHeight="-Infinity" minWidth="-Infinity" name="Selection" prefHeight="336.0" prefWidth="815.0" - spacing="5.0" stylesheets="@theme2.css" xmlns="http://javafx.com/javafx" - fx:controller="fr.pasteur.ida.zellige.gui.controller.SelectionController"> +<?import javafx.scene.layout.ColumnConstraints?> +<?import javafx.scene.layout.FlowPane?> +<?import javafx.scene.layout.GridPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.VBox?> + +<StepPanel maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" name="Selection" prefHeight="336.0" prefWidth="815.0" spacing="5.0" stylesheets="@theme2.css" xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.pasteur.ida.zellige.gui.controller.SelectionController"> <children> <HBox alignment="CENTER" minHeight="-Infinity" minWidth="-Infinity" prefHeight="293.0" prefWidth="815.0"> <children> - <GridPane alignment="CENTER" maxHeight="1.7976931348623157E308" - maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" - prefHeight="265.0" prefWidth="414.0" vgap="5.0" HBox.hgrow="ALWAYS"> + <GridPane alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="265.0" prefWidth="414.0" vgap="5.0" HBox.hgrow="ALWAYS"> <columnConstraints> - <ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" maxWidth="130.0" minWidth="10.0" - percentWidth="5.0" prefWidth="20.0"/> - <ColumnConstraints hgrow="SOMETIMES" maxWidth="235.0" minWidth="10.0" percentWidth="95.0" - prefWidth="214.0"/> + <ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" maxWidth="130.0" minWidth="10.0" percentWidth="5.0" prefWidth="20.0" /> + <ColumnConstraints hgrow="SOMETIMES" maxWidth="235.0" minWidth="10.0" percentWidth="95.0" prefWidth="214.0" /> </columnConstraints> <rowConstraints> - <RowConstraints maxHeight="338.0" minHeight="10.0" prefHeight="205.0" vgrow="SOMETIMES"/> - <RowConstraints maxHeight="446.0" minHeight="10.0" prefHeight="121.0" valignment="CENTER" - vgrow="SOMETIMES"/> + <RowConstraints maxHeight="338.0" minHeight="10.0" prefHeight="205.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="446.0" minHeight="10.0" prefHeight="121.0" valignment="CENTER" vgrow="SOMETIMES" /> </rowConstraints> - <Label alignment="CENTER" minHeight="-Infinity" minWidth="-Infinity" prefHeight="16.0" - prefWidth="100.0" rotate="-90.0" text="CLASSIFICATION" GridPane.halignment="CENTER" - GridPane.valignment="CENTER"/> - <Label alignment="CENTER" minHeight="-Infinity" minWidth="-Infinity" prefHeight="16.0" - prefWidth="100.0" rotate="-90.0" text="SMOOTHING" GridPane.halignment="CENTER" - GridPane.rowIndex="1" GridPane.valignment="CENTER"/> - <VBox alignment="CENTER" prefHeight="168.0" prefWidth="400.0" GridPane.columnIndex="1" - GridPane.halignment="CENTER" GridPane.valignment="CENTER"> - <ParameterSliderInteger fx:id="amplitude" default="10" increment="1" interval="%INTERVAL1" - major="10" max="50" min="0" minor="9" name="Amplitude"/> - <ParameterSliderInteger fx:id="otsu" default="10" increment="1" interval="%INTERVAL1" major="10" - max="50" min="0" minor="9" name="Otsu" GridPane.rowIndex="1"/> - <ParameterSliderInteger fx:id="island" default="5" increment="1" interval="%INTERVAL1" - major="10" max="50" min="0" minor="9" name="Island Search" - GridPane.rowIndex="2"/> + <Label alignment="CENTER" minHeight="-Infinity" minWidth="-Infinity" prefHeight="16.0" prefWidth="100.0" rotate="-90.0" text="CLASSIFICATION" GridPane.halignment="CENTER" GridPane.valignment="CENTER" /> + <Label alignment="CENTER" minHeight="-Infinity" minWidth="-Infinity" prefHeight="16.0" prefWidth="100.0" rotate="-90.0" text="SMOOTHING" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER" /> + <VBox alignment="CENTER" prefHeight="168.0" prefWidth="400.0" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER"> + <ParameterSliderInteger fx:id="amplitude" default="10" increment="1" interval="%INTERVAL1" major="10" max="50" min="0" minor="9" name="Amplitude" /> + <ParameterSliderInteger fx:id="otsu" default="10" increment="1" interval="%INTERVAL1" major="10" max="50" min="0" minor="9" name="Otsu" GridPane.rowIndex="1" /> + <ParameterSliderInteger fx:id="island" default="5" increment="1" interval="%INTERVAL1" major="10" max="50" min="0" minor="9" name="Island Search" GridPane.rowIndex="2" /> </VBox> - <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" GridPane.columnIndex="1" - GridPane.rowIndex="1"> - <ParameterSliderInteger default="1" increment="1" interval="%INTERVAL2" major="2" max="10" - min="0" minor="1" name="XY Blur " GridPane.rowIndex="1" fx:id="xyBlur"/> - <ParameterSliderInteger fx:id="zBlur" default="1" increment="1" interval="%INTERVAL2" major="2" - max="10" min="0" minor="1" name="Z Blur " GridPane.rowIndex="1"/> + <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" GridPane.columnIndex="1" GridPane.rowIndex="1"> + <ParameterSliderInteger default="1" increment="1" interval="%INTERVAL2" major="2" max="10" min="0" minor="1" name="XY Blur " GridPane.rowIndex="1" fx:id="xyBlur" /> + <ParameterSliderInteger fx:id="zBlur" default="1" increment="1" interval="%INTERVAL2" major="2" max="10" min="0" minor="1" name="Z Blur " GridPane.rowIndex="1" /> </VBox> <padding> - <Insets left="5.0" right="5.0" top="5.0"/> + <Insets left="5.0" right="5.0" top="5.0" /> </padding> </GridPane> - <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" - minWidth="-Infinity" prefHeight="293.0" prefWidth="386.0" HBox.hgrow="ALWAYS"> - <FlowPane fx:id="stack" alignment="CENTER" columnHalignment="CENTER" prefHeight="254.0" - prefWidth="401.0" VBox.vgrow="NEVER"/> - <ZSlicesSlider fx:id="zSlices" alignment="CENTER" columnHalignment="CENTER" - maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" - minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="401.0" - VBox.vgrow="ALWAYS"/> + <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="293.0" prefWidth="386.0" HBox.hgrow="ALWAYS"> + <FlowPane fx:id="stack" alignment="CENTER" columnHalignment="CENTER" prefHeight="254.0" prefWidth="401.0" VBox.vgrow="NEVER" /> + <HBox VBox.vgrow="ALWAYS"> + <children> + <ZSlicesSlider fx:id="zSlices" alignment="CENTER" columnHalignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="39.0" prefWidth="338.0" prefWrapLength="300.0" /> + <Button fx:id="pixelSelection" mnemonicParsing="false" text="Run" /> + </children> + </HBox> </VBox> </children> </HBox>