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 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/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/model/data/PositionItem.java b/src/main/java/spim/model/data/PositionItem.java index 599eb234..aa1af6e6 100644 --- a/src/main/java/spim/model/data/PositionItem.java +++ b/src/main/java/spim/model/data/PositionItem.java @@ -1,5 +1,11 @@ package spim.model.data; +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. * @@ -15,12 +21,14 @@ public class PositionItem private double zStart; private double zEnd; private double zStep; + private final BooleanProperty selected = new SimpleBooleanProperty(); + private final StringProperty name = new SimpleStringProperty(); 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 +36,8 @@ 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 ) ); } public double getX() @@ -74,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; @@ -105,7 +121,21 @@ 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; } + + public boolean getSelected() { + return selected.get(); + } + + public void setSelected(boolean selected) { + this.selected.set( selected ); + } + + public void setName(String name) { + this.name.set(name); } @Override public String toString() diff --git a/src/main/java/spim/ui/view/component/AcquisitionPanel.java b/src/main/java/spim/ui/view/component/AcquisitionPanel.java index d4a33bd7..d776fa1f 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() ); } } ); @@ -1207,6 +1208,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() ); @@ -1353,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.", @@ -1462,7 +1470,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 +1523,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 +1532,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 +1620,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 +1863,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 ); @@ -2097,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) { @@ -2134,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")); @@ -2148,13 +2161,15 @@ 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; } 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 +2179,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/MMAcquisitionEngine.java b/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java index 7111cf26..0fe4b6ff 100644 --- a/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java +++ b/src/main/java/spim/ui/view/component/MMAcquisitionEngine.java @@ -380,13 +380,15 @@ 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)); } } } 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/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 ); } 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()) { 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 { 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 50c3fc4d..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; @@ -118,6 +122,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 ); @@ -150,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( "-" ); @@ -158,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 ); @@ -193,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>() { 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.