From ea6294787cb71769fe2738269fc8819954781546 Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Thu, 27 Jan 2022 16:59:20 +0100 Subject: [PATCH 01/10] Used sigma = 2 for gaussian blur Then, convolve filter and maximum filter --- .../java/spim/algorithm/DefaultAntiDrift.java | 15 ++++++++++++++- .../ui/view/component/MMAcquisitionEngine.java | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/spim/algorithm/DefaultAntiDrift.java b/src/main/java/spim/algorithm/DefaultAntiDrift.java index 476d0fad..bf984d53 100644 --- a/src/main/java/spim/algorithm/DefaultAntiDrift.java +++ b/src/main/java/spim/algorithm/DefaultAntiDrift.java @@ -1,6 +1,9 @@ package spim.algorithm; import ij.ImageStack; +import ij.plugin.filter.Convolver; +import ij.plugin.filter.GaussianBlur; +import ij.plugin.filter.RankFilters; import ij.process.*; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -18,6 +21,14 @@ public class DefaultAntiDrift extends AbstractAntiDrift */ private final double sigma; private final AntiDrift.Type type; + private final GaussianBlur gaussianBlur = new GaussianBlur(); + private final Convolver convolver = new Convolver(); + private final RankFilters filters = new RankFilters(); + private final float[] kernel = new float[]{-1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, + -1, -1, 24, -1, -1, + -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1,}; public DefaultAntiDrift(double sigmaValue) { @@ -49,6 +60,9 @@ public void reset() @Override public void addXYSlice( ImageProcessor ip ) { ImageProcessor copy = ip.duplicate(); + gaussianBlur.blurGaussian( copy, sigma ); + convolver.convolve( copy, kernel, 5, 5 ); + filters.rank( copy, 2, 2 ); switch (type) { case CenterOfMass: @@ -56,7 +70,6 @@ public void reset() stack.addSlice( copy ); break; case PhaseCorrelation: - copy.blurGaussian( sigma ); latest.addXYSlice( copy ); break; } diff --git a/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java b/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java index 7111cf26..0d819771 100644 --- a/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java +++ b/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java @@ -380,7 +380,7 @@ private void runNormalSmartImagingMMAcq(SPIMSetup setup, final Studio frame, Dat if(toogleGroupValue.equals("Centre of mass")) { driftCompMap.put(positionItem, new DefaultAntiDrift()); } else if(toogleGroupValue.equals("Phase correlation")) { - driftCompMap.put(positionItem, new DefaultAntiDrift(10)); + driftCompMap.put(positionItem, new DefaultAntiDrift(2)); } } } From 6bb6cc083d565747f79de5cf4a8abef5716d5a73 Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 10:03:02 +0100 Subject: [PATCH 02/10] Close #188: Tickboxes of the positions --- .../java/spim/model/data/PositionItem.java | 18 +++++++++++- .../ui/view/component/AcquisitionPanel.java | 29 ++++++++++++++----- .../ui/view/component/util/TableViewUtil.java | 6 ++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/main/java/spim/model/data/PositionItem.java b/src/main/java/spim/model/data/PositionItem.java index 599eb234..60dd1fa4 100644 --- a/src/main/java/spim/model/data/PositionItem.java +++ b/src/main/java/spim/model/data/PositionItem.java @@ -1,5 +1,9 @@ package spim.model.data; +import javafx.beans.InvalidationListener; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; + /** * Description: PositionItem is used for position table. * @@ -15,12 +19,13 @@ public class PositionItem private double zStart; private double zEnd; private double zStep; + private final BooleanProperty selected = new SimpleBooleanProperty(); public PositionItem() { } - public PositionItem( double x, double y, double r, double zStart, double zEnd, double zStep ) + public PositionItem( double x, double y, double r, double zStart, double zEnd, double zStep, InvalidationListener invalidationListener ) { this.x = x; this.y = y; @@ -28,6 +33,7 @@ public PositionItem( double x, double y, double r, double zStart, double zEnd, d this.zStart = zStart; this.zEnd = zEnd; this.zStep = zStep; + selectedProperty().addListener( observable -> invalidationListener.invalidated( observable ) ); } public double getX() @@ -108,6 +114,16 @@ public int getNumberOfSlices() { return (int) ((int) (getZEnd() - getZStart() + getZStep()) / getZStep()); } + public BooleanProperty selectedProperty() { return selected; } + + public boolean getSelected() { + return selected.get(); + } + + public void setSelected(boolean selected) { + this.selected.set( selected ); + } + @Override public String toString() { StringBuilder sb = new StringBuilder( ); diff --git a/src/main/java/spim/ui/view/component/AcquisitionPanel.java b/src/main/java/spim/ui/view/component/AcquisitionPanel.java index d4a33bd7..8e62c1fb 100644 --- a/src/main/java/spim/ui/view/component/AcquisitionPanel.java +++ b/src/main/java/spim/ui/view/component/AcquisitionPanel.java @@ -1207,6 +1207,13 @@ private void updateUI ( AcquisitionSetting setting ) { positionItems = setting.getPositionItems(); positionItemTableView.getItems().setAll( positionItems ); + InvalidationListener invalidationListener = observable -> computeTotalPositionImages(); + for(int i = 0; i < positionItems.size(); i++) { +// positionItems.get( i ).setValue( positionItems.get(i).getValue() ); +// positionItems.get( i ).setSelected( positionItems.get(i).getSelected() ); + positionItems.get( i ).selectedProperty().addListener( observable -> invalidationListener.invalidated( observable ) ); + } + // 3. Z-Stack panel enabledZStacks.set( setting.getEnabledZStacks() ); @@ -1462,7 +1469,7 @@ public boolean startAcquisition( Button acquireButton ) engine.performAcquisition( getStudio(), getSpimSetup(), stagePanel, ( java.awt.Rectangle) roiRectangle.get(), tp, timePointItemTableView.getItems(), currentTP, waitSeconds, arduinoSelected, finalFolder, filename.getValue(), - positionItemTableView.getItems(), channelItemList, processedImages, + positionItemTableView.getItems().filtered(p -> p.getSelected()), channelItemList, processedImages, enabledSaveImages.get(), savingFormat.getValue(), saveMIP.getValue(), antiDrift.getValue(), experimentNote.getValue(), antiDriftLog, antiDriftRefCh.get(), antiDriftTypeToggle, onTheFly.getValue() ); @@ -1515,6 +1522,8 @@ static double getUnit(String unitString) { private Node createPositionListPane( TableView< PositionItem > positionItemTableView ) { positionItemTableView.setEditable( true ); + InvalidationListener invalidationListener = observable -> computeTotalPositionImages(); + EventHandler newEventHandler = ( EventHandler< ActionEvent > ) event -> { SPIMSetup spimSetup = getSpimSetup(); if(spimSetup != null ) { @@ -1522,10 +1531,10 @@ private Node createPositionListPane( TableView< PositionItem > positionItemTable double x = spimSetup.getXStage().getPosition(); double y = spimSetup.getYStage().getPosition(); double z = spimSetup.getZStage().getPosition(); - positionItemTableView.getItems().add( new PositionItem( x, y, r, z, z, zStackStepSize ) ); + positionItemTableView.getItems().add( new PositionItem( x, y, r, z, z, zStackStepSize, invalidationListener ) ); } else { - positionItemTableView.getItems().add( new PositionItem( 10, 20, 30, 20, 50, 10 ) ); + positionItemTableView.getItems().add( new PositionItem( 10, 20, 30, 20, 50, 10, invalidationListener ) ); } }; @@ -1610,12 +1619,12 @@ public void computeTotalPositionImages() { long totalImages = 0; for(PositionItem item : positionItemTableView.getItems()) { - if(item.getZEnd() > item.getZStart()) { + if(item.getSelected() && item.getZEnd() > item.getZStart()) { totalImages += item.getNumberOfSlices(); } } - propertyMap.get("positions").setValue( positionItemTableView.getItems().size() + "" ); + propertyMap.get("positions").setValue( positionItemTableView.getItems().filtered(p -> p.getSelected()).size() + "" ); propertyMap.get("slices").setValue( totalImages + "" ); } @@ -1853,6 +1862,8 @@ private LabeledPane createSummaryPane() { label.textProperty().bind( propertyMap.get("positions") ); label.textProperty().addListener( observable -> computeTotal() ); + propertyMap.get("slices").addListener( observable -> computeTotal() ); + Label label2 = new Label(); label2.textProperty().bind( propertyMap.get("totalImages") ); gridpane.addRow( 0, new Label("No. of positions: "), label, new Label("Total images: "), label2 ); @@ -2155,6 +2166,8 @@ public void handle(ActionEvent event) { private void addNewPosition( int zStart, int zEnd, double zStep ) { SPIMSetup spimSetup = getSpimSetup(); + InvalidationListener invalidationListener = observable -> computeTotalPositionImages(); + if(spimSetup != null ) { double r = spimSetup.getThetaStage().getPosition(); double x = spimSetup.getXStage().getPosition(); @@ -2164,13 +2177,13 @@ private void addNewPosition( int zStart, int zEnd, double zStep ) { if( zStart < 0 && zEnd < 0 ) { double z = spimSetup.getZStage().getPosition(); - positionItemTableView.getItems().add(new PositionItem(x, y, r, z, z, zStep)); + positionItemTableView.getItems().add(new PositionItem(x, y, r, z, z, zStep, invalidationListener)); } else { - positionItemTableView.getItems().add(new PositionItem(x, y, r, zStart, zEnd, zStep)); + positionItemTableView.getItems().add(new PositionItem(x, y, r, zStart, zEnd, zStep, invalidationListener)); } } else { - positionItemTableView.getItems().add( new PositionItem( 10, 20, 30, zStart, zEnd, zStep ) ); + positionItemTableView.getItems().add( new PositionItem( 10, 20, 30, zStart, zEnd, zStep, invalidationListener ) ); } } diff --git a/src/main/java/spim/ui/view/component/util/TableViewUtil.java b/src/main/java/spim/ui/view/component/util/TableViewUtil.java index 50c3fc4d..d087c5f2 100644 --- a/src/main/java/spim/ui/view/component/util/TableViewUtil.java +++ b/src/main/java/spim/ui/view/component/util/TableViewUtil.java @@ -118,6 +118,12 @@ public void handle(MouseEvent event) { return cell; } }; + TableColumn booleanColumn = new TableColumn<>(""); + booleanColumn.setPrefWidth( 20 ); + booleanColumn.setCellValueFactory( new PropertyValueFactory<>( "selected" ) ); + booleanColumn.setCellFactory( tc -> new CheckBoxTableCell<>() ); + booleanColumn.setOnEditCommit( event -> event.getRowValue().setSelected( event.getNewValue() ) ); + tv.getColumns().add( booleanColumn ); TableColumn numberColumn = new TableColumn<>( "#" ); numberColumn.setPrefWidth( 20 ); From 02c8b68df91a74f751e6b6ad1eeadf19e358989a Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 10:38:27 +0100 Subject: [PATCH 03/10] Close #190: Wrong percentage indicator --- src/main/java/spim/model/data/PositionItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/spim/model/data/PositionItem.java b/src/main/java/spim/model/data/PositionItem.java index 60dd1fa4..31ca78a3 100644 --- a/src/main/java/spim/model/data/PositionItem.java +++ b/src/main/java/spim/model/data/PositionItem.java @@ -111,7 +111,7 @@ public void setZStep( double zStep ) } public int getNumberOfSlices() { - return (int) ((int) (getZEnd() - getZStart() + getZStep()) / getZStep()); + return (int) ((int) (getZEnd() - getZStart() + getZStep()) / getZStep() + 1); } public BooleanProperty selectedProperty() { return selected; } From 449fb450b137169dd6971efebe48a149de6764b5 Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 10:39:13 +0100 Subject: [PATCH 04/10] Remove the verbose messages --- src/main/java/spim/mm/MicroManager.java | 6 +++--- .../java/spim/ui/view/component/AcquisitionPanel.java | 1 + .../spim/ui/view/component/MMAcquisitionEngine.java | 10 ++++++---- .../ui/view/component/acquisition/TaggedImageSink.java | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/spim/mm/MicroManager.java b/src/main/java/spim/mm/MicroManager.java index a91e29c8..508b6bb6 100644 --- a/src/main/java/spim/mm/MicroManager.java +++ b/src/main/java/spim/mm/MicroManager.java @@ -1331,14 +1331,14 @@ public static void shutdown() @Subscribe public void onAcquisitionStart( AcquisitionStartedEvent ae) { - System.out.println("Acquisition started"); +// System.out.println("Acquisition started"); // store_ = ae.getDatastore(); } @Subscribe public void onAcquisitionEnd( AcquisitionEndedEvent ae) { - System.out.println("Acquisition stopped"); +// System.out.println("Acquisition stopped"); // store_ = null; } @@ -1349,7 +1349,7 @@ public void onSystemConfigurationLoaded(SystemConfigurationLoadedEvent event) { @Subscribe public void onStagePositionChanged(StagePositionChangedEvent event) { - System.out.println("Stage changed"); +// System.out.println("Stage changed"); } @Subscribe diff --git a/src/main/java/spim/ui/view/component/AcquisitionPanel.java b/src/main/java/spim/ui/view/component/AcquisitionPanel.java index 8e62c1fb..882a1fbd 100644 --- a/src/main/java/spim/ui/view/component/AcquisitionPanel.java +++ b/src/main/java/spim/ui/view/component/AcquisitionPanel.java @@ -389,6 +389,7 @@ public AcquisitionPanel(SPIMSetup setup, Studio studio, StagePanel stagePanel, T { @Override public void changed( ObservableValue< ? extends Number > observable, Number oldValue, Number newValue ) { +// System.out.println(String.format("%f / %d", newValue.doubleValue(), totalImages.getValue())); pi.setProgress( newValue.doubleValue() / totalImages.getValue() ); } } ); diff --git a/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java b/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java index 0d819771..0fe4b6ff 100644 --- a/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java +++ b/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java @@ -387,6 +387,8 @@ private void runNormalSmartImagingMMAcq(SPIMSetup setup, final Studio frame, Dat AcqWrapperEngine engine = new AcqWrapperEngine( setup, frame, store, currentCamera, cameras, outFolder, acqFilenamePrefix, channelItems, arduinoSelected, processedImages, driftCompMap, adReferenceChannel, onTheFly); + SystemInfo.dumpMemoryStatusToLog(core); + mainLoop: for(TimePointItem tpItem : timePointItems ) { if(tpItem.getType().equals( TimePointItem.Type.Acq )) @@ -398,8 +400,6 @@ private void runNormalSmartImagingMMAcq(SPIMSetup setup, final Studio frame, Dat int step = 0; - SystemInfo.dumpMemoryStatusToLog(core); - for ( PositionItem positionItem : positionItems ) { final int tp = timePoints; @@ -482,7 +482,7 @@ private void runNormalSmartImagingMMAcq(SPIMSetup setup, final Studio frame, Dat } core.logMessage("MMAcquisition started"); - System.out.println("MMAcquisition started"); +// System.out.println("MMAcquisition started"); engine.startAcquire( timePoints, step, positionItem ); while(engine.isAcquisitionRunning()) { @@ -498,7 +498,7 @@ private void runNormalSmartImagingMMAcq(SPIMSetup setup, final Studio frame, Dat } core.logMessage("MMAcquisition finished"); - System.out.println("MMAcquisition finished"); +// System.out.println("MMAcquisition finished"); if(setup.getArduino1() != null) setup.getArduino1().setSwitchState( "0" ); @@ -594,6 +594,8 @@ else if(tpItem.getType().equals( TimePointItem.Type.Wait )) } } + SystemInfo.dumpMemoryStatusToLog(core); + engine.exit(); store.freeze(); System.err.println("AcquisitionEngine exited."); diff --git a/src/main/java/spim/ui/view/component/acquisition/TaggedImageSink.java b/src/main/java/spim/ui/view/component/acquisition/TaggedImageSink.java index b47ce3e3..b2a5674b 100644 --- a/src/main/java/spim/ui/view/component/acquisition/TaggedImageSink.java +++ b/src/main/java/spim/ui/view/component/acquisition/TaggedImageSink.java @@ -134,7 +134,7 @@ public void run() { if (tagged != null) { if ( TaggedImageQueue.isPoison(tagged)) { // Acquisition has ended. Clean up under "finally" - System.out.println("IsPoison"); +// System.out.println("IsPoison"); break; } try { From a0730108e94aa43a22b2df00b9e85c7efeafb12a Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 11:23:52 +0100 Subject: [PATCH 05/10] Close #189: False warning sign that there is the filename already exists --- src/main/java/spim/ui/view/component/AcquisitionPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/spim/ui/view/component/AcquisitionPanel.java b/src/main/java/spim/ui/view/component/AcquisitionPanel.java index 882a1fbd..1b0a8892 100644 --- a/src/main/java/spim/ui/view/component/AcquisitionPanel.java +++ b/src/main/java/spim/ui/view/component/AcquisitionPanel.java @@ -1361,7 +1361,7 @@ public boolean startAcquisition( Button acquireButton ) if ( enabledSaveImages.get() ) { if(null != folder.listFiles()) { - boolean found = folder.exists(); + boolean found = folder.exists() && folder.listFiles().length > 1; if(found) { Optional< ButtonType > results = new Alert( Alert.AlertType.WARNING, "The filename already exists. All files with the same name will be replaced. Do you want to proceed?\nPress No to create another folder and keep all files.", From e61a39d3e812f8fd038193bcecc7ed9babc9d667 Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 11:24:44 +0100 Subject: [PATCH 06/10] Remove null-MPI issue when unchecked MIP option --- .../spim/ui/view/component/acquisition/AcqWrapperEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/spim/ui/view/component/acquisition/AcqWrapperEngine.java b/src/main/java/spim/ui/view/component/acquisition/AcqWrapperEngine.java index 022945df..8f0d2ef9 100644 --- a/src/main/java/spim/ui/view/component/acquisition/AcqWrapperEngine.java +++ b/src/main/java/spim/ui/view/component/acquisition/AcqWrapperEngine.java @@ -228,7 +228,7 @@ public AcqWrapperEngine(SPIMSetup setup, final Studio frame, Datastore store, channels_ = channels; setChannelGroup( channelGroupName ); - if ( outFolder != null ) { + if ( outFolder != null && acqFilenamePrefix != null ) { File saveDir = new File(outFolder, acqFilenamePrefix + "-MIP"); if (!outFolder.exists() && !outFolder.mkdirs()) { From 6382244c28bac307526c5922da0a16d1b0b66906 Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 11:33:23 +0100 Subject: [PATCH 07/10] Update labels for Z-Stacks --- src/main/java/spim/ui/view/component/AcquisitionPanel.java | 7 ++++--- src/main/resource/spim/help/DefineZStacks.html | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/spim/ui/view/component/AcquisitionPanel.java b/src/main/java/spim/ui/view/component/AcquisitionPanel.java index 1b0a8892..d776fa1f 100644 --- a/src/main/java/spim/ui/view/component/AcquisitionPanel.java +++ b/src/main/java/spim/ui/view/component/AcquisitionPanel.java @@ -2109,7 +2109,8 @@ public void changed(ObservableValue observable, String oldValu // } // } ); - Button clearButton = new Button( "New Z-stack" ); + Button clearButton = new Button( "Define new Z-stack" ); + clearButton.setStyle("-fx-base: #ffbec4;"); clearButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { @@ -2146,7 +2147,7 @@ public void handle(ActionEvent event) { } } ); - zStackGridPane.addRow( 3, new HBox( newButton, clearButton ) ); + zStackGridPane.addRow( 3, new VBox( newButton, clearButton ) ); // create a group HBox b = new HBox(new Label("Stage")); @@ -2160,7 +2161,7 @@ public void handle(ActionEvent event) { Button helpButton = createHelpButton(); helpButton.setOnAction( event -> new HelpWindow().show(HelpType.ZSTACK)); - CheckboxPane pane = new CheckboxPane( "Define Z-stacks", zStackGroup, helpButton ); + CheckboxPane pane = new CheckboxPane( "Z-stacks", zStackGroup, helpButton ); enabledZStacks = pane.selectedProperty(); return pane; } diff --git a/src/main/resource/spim/help/DefineZStacks.html b/src/main/resource/spim/help/DefineZStacks.html index 0386e27b..f48b23a6 100644 --- a/src/main/resource/spim/help/DefineZStacks.html +++ b/src/main/resource/spim/help/DefineZStacks.html @@ -33,7 +33,7 @@ -

Define Z-stacks

+

Z-stacks

Here the beginning and the end of a new stack together with its Z step size can be specified using the Z stage. One has to first find the sample and a centre it in the field of view. By navigating through the sample along the z-axis the beginning and end of a z-stack is specified.

@@ -55,7 +55,7 @@

Define Z-stacks

  • It is possible to manually change any positional values by double-clicking on one of the positional entries. Note that this can be done during an ongoing imaging session.
  • -
    New Z-stack
    +
    Define new Z-stack
    Clicking this button will clear all previously locked Z-stack values in order to define a new Z-stack.
  • It is possible to manually change any positional values by double-clicking on one of the positional entries. Note that this can be done during an ongoing imaging session.
  • From 1f99a3124bfd756fce80da7cbdff3f5393e7904b Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 12:59:29 +0100 Subject: [PATCH 08/10] #119: Add position name and color to distinguish "Stack" and "Position" in the position list --- .../java/spim/model/data/PositionItem.java | 14 +++ .../util/StackPositionTableCell.java | 106 ++++++++++++++++++ .../ui/view/component/util/TableViewUtil.java | 16 ++- 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/main/java/spim/ui/view/component/util/StackPositionTableCell.java diff --git a/src/main/java/spim/model/data/PositionItem.java b/src/main/java/spim/model/data/PositionItem.java index 31ca78a3..aa1af6e6 100644 --- a/src/main/java/spim/model/data/PositionItem.java +++ b/src/main/java/spim/model/data/PositionItem.java @@ -3,6 +3,8 @@ import javafx.beans.InvalidationListener; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; /** * Description: PositionItem is used for position table. @@ -20,6 +22,7 @@ public class PositionItem private double zEnd; private double zStep; private final BooleanProperty selected = new SimpleBooleanProperty(); + private final StringProperty name = new SimpleStringProperty(); public PositionItem() { @@ -33,6 +36,7 @@ public PositionItem( double x, double y, double r, double zStart, double zEnd, d this.zStart = zStart; this.zEnd = zEnd; this.zStep = zStep; + this.name.set(""); selectedProperty().addListener( observable -> invalidationListener.invalidated( observable ) ); } @@ -80,6 +84,12 @@ public String getPosZString() { return String.format( "%.0f", zStart ); } + public String getName() { + return name.getValue(); + } + + public StringProperty getNameProperty() { return name; } + public void setX( double x ) { this.x = x; @@ -124,6 +134,10 @@ public void setSelected(boolean selected) { this.selected.set( selected ); } + public void setName(String name) { + this.name.set(name); + } + @Override public String toString() { StringBuilder sb = new StringBuilder( ); diff --git a/src/main/java/spim/ui/view/component/util/StackPositionTableCell.java b/src/main/java/spim/ui/view/component/util/StackPositionTableCell.java new file mode 100644 index 00000000..5e9a69fb --- /dev/null +++ b/src/main/java/spim/ui/view/component/util/StackPositionTableCell.java @@ -0,0 +1,106 @@ +package spim.ui.view.component.util; + +import javafx.event.EventHandler; +import javafx.scene.Node; +import javafx.scene.control.Cell; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableRow; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.input.MouseEvent; +import javafx.util.Callback; +import javafx.util.StringConverter; +import javafx.util.converter.DefaultStringConverter; +import spim.model.data.PositionItem; + +/** + * Description: To render different color for "Position" type and "Stack" type for Position Item + * + * Author: HongKee Moon (moon@mpi-cbg.de), Scientific Computing Facility + * Organization: MPI-CBG Dresden + * Date: March 2022 + */ +public class StackPositionTableCell extends TextFieldTableCell +{ + public static Callback, TableCell> forTableColumn() { + return forTableColumn(new DefaultStringConverter()); + } + + public static Callback, TableCell> forTableColumn( + final StringConverter converter) { + return list -> new StackPositionTableCell(converter); + } + + static StackPositionTableCell lastCell; + + StackPositionTableCell(StringConverter converter) { + super(converter); + this.addEventFilter( MouseEvent.MOUSE_CLICKED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + if (event.getClickCount() > 1) { + StackPositionTableCell c = (StackPositionTableCell) event.getSource(); + lastCell = c; + lastCell.startSuperStartEdit(); + } else { + if (lastCell != null && !lastCell.equals(event.getSource())) { + lastCell.cancelEdit(); + lastCell = null; + } + } + } + }); + } + + @Override public void startEdit() { + if (! isEditable() + || ! getTableView().isEditable() + || ! getTableColumn().isEditable()) { + return; + } + } + + /** {@inheritDoc} */ + @Override public void updateItem(T item, boolean empty) { + super.updateItem(item, empty); + this.updateItem(this, getConverter(), null); + } + + void updateItem(final Cell cell, + final StringConverter converter, + final Node graphic) { + if (cell.isEmpty()) { + cell.setText(null); + cell.setGraphic(null); + setStyle( "" ); + } else { + if (cell.isEditing()) { + cell.setText(null); + } else { + TableRow row = getTableRow(); + T item = row.getItem(); + if( item instanceof PositionItem) { + PositionItem tItem = ( PositionItem ) item; + + if(tItem.getZStart() == tItem.getZEnd()) + cell.setStyle( "-fx-background-color: -fx-background; -fx-background: #ffecea;" ); + else + cell.setStyle( "-fx-background-color: -fx-background; -fx-background: #e0ffe4;" ); + } + + cell.setText(getItemText(cell, converter)); + cell.setGraphic(graphic); + } + } + } + + private String getItemText(Cell cell, StringConverter converter) { + return converter == null ? + cell.getItem() == null ? "" : cell.getItem().toString() : + converter.toString(cell.getItem()); + } + + void startSuperStartEdit() { + super.startEdit(); + } +} \ No newline at end of file diff --git a/src/main/java/spim/ui/view/component/util/TableViewUtil.java b/src/main/java/spim/ui/view/component/util/TableViewUtil.java index d087c5f2..d6052fbf 100644 --- a/src/main/java/spim/ui/view/component/util/TableViewUtil.java +++ b/src/main/java/spim/ui/view/component/util/TableViewUtil.java @@ -2,9 +2,11 @@ import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon; import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView; +import javafx.beans.binding.Bindings; import javafx.beans.property.ReadOnlyDoubleWrapper; import javafx.beans.property.ReadOnlyIntegerWrapper; import javafx.beans.property.ReadOnlyStringWrapper; +import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -13,6 +15,7 @@ import javafx.event.EventHandler; import javafx.geometry.Pos; +import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.ContentDisplay; @@ -26,6 +29,7 @@ import javafx.scene.control.cell.CheckBoxTableCell; import javafx.scene.control.cell.ChoiceBoxTableCell; import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.input.ClipboardContent; import javafx.scene.input.DataFormat; import javafx.scene.input.Dragboard; @@ -156,7 +160,7 @@ public void handle(MouseEvent event) { column.setCellValueFactory( (param) -> new ReadOnlyStringWrapper( param.getValue().getZString() ) ); - column.setCellFactory( NumberFieldTableCell.forTableColumn() ); + column.setCellFactory( StackPositionTableCell.forTableColumn() ); column.setOnEditCommit( event -> { String zString = event.getNewValue(); String[] tokens = zString.split( "-" ); @@ -164,11 +168,14 @@ public void handle(MouseEvent event) { if(tokens.length == 2) { event.getRowValue().setZStart( Double.parseDouble( tokens[0] ) ); event.getRowValue().setZEnd( Double.parseDouble( tokens[1] ) ); +// event.getTableColumn().setStyle( "-fx-background-color: -fx-background; -fx-background: #e0ffe4;" ); } else if(tokens.length == 1) { event.getRowValue().setZStart( Double.parseDouble( tokens[0] ) ); event.getRowValue().setZStep( 1 ); event.getRowValue().setZEnd( Double.parseDouble( tokens[0] ) ); +// event.getTableColumn().setStyle( "-fx-background-color: -fx-background; -fx-background: #ffecea;" ); } + event.getTableView().refresh(); // invoke selected item changed! cascadeUpdatedValues( acquisitionPanel, tv ); @@ -199,6 +206,13 @@ public void handle(MouseEvent event) { numberColumn.setEditable( true ); tv.getColumns().add(numberColumn); + TableColumn textColumn = new TableColumn<>("Name"); + textColumn.setPrefWidth(100); + textColumn.setCellValueFactory( param -> param.getValue().getNameProperty() ); + textColumn.setCellFactory( TextFieldTableCell.forTableColumn() ); + textColumn.setOnEditCommit( event -> event.getRowValue().setName( event.getNewValue() ) ); + tv.getColumns().add(textColumn); + TableColumn btnColumn = new TableColumn<>(""); btnColumn.setPrefWidth(130); Callback, TableCell> cellFactory = new Callback, TableCell>() { From aca75a5253c24bd006bad08c6a52b97da87e0522 Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 13:31:27 +0100 Subject: [PATCH 09/10] #119: Add the name for "Save current position" --- .../spim/ui/view/component/StagePanel.java | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/main/java/spim/ui/view/component/StagePanel.java b/src/main/java/spim/ui/view/component/StagePanel.java index 141a57d5..5e7b951c 100644 --- a/src/main/java/spim/ui/view/component/StagePanel.java +++ b/src/main/java/spim/ui/view/component/StagePanel.java @@ -39,6 +39,7 @@ import java.io.FileOutputStream; import java.util.ArrayList; import java.util.HashMap; +import java.util.Optional; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -431,10 +432,20 @@ private VBox createControls() for(String str : stack.getList()) { MenuItem newItem = new MenuItem( str ); String[] tokens = str.split( ":" ); - double r = Double.parseDouble( tokens[0] ); - double x = Double.parseDouble( tokens[1] ); - double y = Double.parseDouble( tokens[2] ); - double z = Double.parseDouble( tokens[3] ); + + double r, x, y, z; + + if(tokens.length == 5) { + r = Double.parseDouble( tokens[1] ); + x = Double.parseDouble( tokens[2] ); + y = Double.parseDouble( tokens[3] ); + z = Double.parseDouble( tokens[4] ); + } else { + r = Double.parseDouble( tokens[0] ); + x = Double.parseDouble( tokens[1] ); + y = Double.parseDouble( tokens[2] ); + z = Double.parseDouble( tokens[3] ); + } newItem.setOnAction( event -> { stageUnitR.setCurrentPos(r); @@ -473,11 +484,24 @@ private VBox createControls() double y = stageUnitY.getCurrentValue(); double z = stageUnitZ.getCurrentValue(); - System.out.println(String.format( "Saved location - R: %.1f, X: %.1f, Y: %.1f, Z: %.1f", - r, x, y, z)); + // create a text input dialog + TextInputDialog td = new TextInputDialog("Enter name for position"); + String returnedName = ""; + + // setHeaderText + td.setHeaderText("Enter the position name"); + + // show the dialog and wait for the name + Optional result = td.showAndWait(); + if (result.isPresent()) { + returnedName = td.getEditor().getText().replace(":", ""); + } + + System.out.println(String.format( "Saved location - Name: %s, R: %.1f, X: %.1f, Y: %.1f, Z: %.1f", + returnedName, r, x, y, z)); - String newLocation = String.format( "%.1f:%.1f:%.1f:%.1f", - r, x, y, z); + String newLocation = String.format( "%s:%.1f:%.1f:%.1f:%.1f", + returnedName, r, x, y, z); stack.add( newLocation ); } From 5161e97daf621835587c1410b529b301915e6061 Mon Sep 17 00:00:00 2001 From: HongKee Moon Date: Tue, 22 Mar 2022 14:39:34 +0100 Subject: [PATCH 10/10] Bump to 1.0.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5453b265..16941696 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.openspim uOpenSPIM - 1.0.4-SNAPSHOT + 1.0.5-SNAPSHOT jar µOpenSPIM