From bc163584e28748bbfbe34e5b3642b5d7adec415b Mon Sep 17 00:00:00 2001
From: Thomas <thomas.musset@pasteur.fr>
Date: Thu, 27 Jun 2024 20:28:44 +0200
Subject: [PATCH] updated pom to v5.0.0-a.1, fix classes accordingly to new
 architecture, added icon, updated .gitignore

---
 .gitignore                                    |  44 +++-
 pom.xml                                       |  13 +-
 .../ConnectedComponent.java                   |  30 +--
 .../ConnectedComponentDescriptor.java         |  14 +-
 .../ConnectedComponents.java                  | 218 +++++++++---------
 .../resources/icon/Connected_Components.png   | Bin 0 -> 7851 bytes
 6 files changed, 168 insertions(+), 151 deletions(-)
 create mode 100644 src/main/resources/icon/Connected_Components.png

diff --git a/.gitignore b/.gitignore
index b2f15ce..57f16fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,41 @@
-.idea/
-.settings/
-build/
+/build*
+/workspace
+setting.xml
+release/
 target/
-bin/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+icy.log
+
+### IntelliJ IDEA ###
+.idea/
+*.iws
 *.iml
-*.jar
+*.ipr
+
+### Eclipse ###
+.apt_generated
 .classpath
+.factorypath
 .project
-export.jardesc
-**/.DS_Store
\ No newline at end of file
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+**/.DS_Store
+Icon?
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 061aeba..107ccb9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,13 +7,11 @@
     <parent>
         <groupId>org.bioimageanalysis.icy</groupId>
         <artifactId>pom-icy</artifactId>
-        <version>2.2.0</version>
+        <version>3.0.0-a.1</version>
     </parent>
 
     <artifactId>connected-components</artifactId>
-    <version>5.0.0</version>
-
-    <packaging>jar</packaging>
+    <version>5.0.0-a.1</version>
 
     <name>ConnectedComponents</name>
     <description>
@@ -48,17 +46,12 @@
             <groupId>org.bioimageanalysis.icy</groupId>
             <artifactId>jama</artifactId>
         </dependency>
-
-        <dependency>
-            <groupId>net.sourceforge.jexcelapi</groupId>
-            <artifactId>jxl</artifactId>
-        </dependency>
     </dependencies>
 
     <repositories>
         <repository>
             <id>icy</id>
-            <url>https://icy-nexus.pasteur.fr/repository/Icy/</url>
+            <url>https://nexus-icy.pasteur.cloud/repository/icy/</url>
         </repository>
     </repositories>
 
diff --git a/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponent.java b/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponent.java
index dfa7b47..fa8fa12 100644
--- a/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponent.java
+++ b/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,15 +18,17 @@
 
 package plugins.adufour.connectedcomponents;
 
-import icy.image.IcyBufferedImage;
-import icy.roi.ROI;
-import icy.sequence.Sequence;
-import icy.sequence.SequenceDataIterator;
-import icy.type.DataIteratorUtil;
-import icy.type.DataType;
-import icy.type.collection.array.Array1DUtil;
-import plugins.kernel.roi.roi2d.ROI2DArea;
-import plugins.kernel.roi.roi3d.ROI3DArea;
+
+import org.bioimageanalysis.extension.kernel.roi.roi2d.ROI2DArea;
+import org.bioimageanalysis.extension.kernel.roi.roi3d.ROI3DArea;
+import org.bioimageanalysis.icy.common.collection.array.Array1DUtil;
+import org.bioimageanalysis.icy.common.type.DataIteratorUtil;
+import org.bioimageanalysis.icy.common.type.DataType;
+import org.bioimageanalysis.icy.model.image.IcyBufferedImage;
+import org.bioimageanalysis.icy.model.roi.ROI;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.model.sequence.SequenceDataIterator;
+import org.jetbrains.annotations.NotNull;
 import plugins.nchenouard.spot.Detection;
 
 import javax.vecmath.Point3d;
@@ -182,7 +184,7 @@ public class ConnectedComponent extends Detection implements Iterable<Point3i> {
 
             for (int c = 0; c < intensitySum.length; c++)
                 intensitySum[c] += Array1DUtil.getValue(((Object[]) dataCXY)[c], offsetXY,
-                        sequence.getDataType_().isSigned());
+                        sequence.getDataType().isSigned());
         }
 
         for (int i = 0; i < intensitySum.length; i++)
@@ -220,7 +222,7 @@ public class ConnectedComponent extends Detection implements Iterable<Point3i> {
 
             for (int c = 0; c < minIntensity.length; c++) {
                 final double val = Array1DUtil.getValue(((Object[]) dataCXY)[c], offsetXY,
-                        sequence.getDataType_().isSigned());
+                        sequence.getDataType().isSigned());
                 if (val < minIntensity[c])
                     minIntensity[c] = val;
             }
@@ -257,7 +259,7 @@ public class ConnectedComponent extends Detection implements Iterable<Point3i> {
 
             for (int c = 0; c < maxIntensity.length; c++) {
                 final double val = Array1DUtil.getValue(((Object[]) dataCXY)[c], offsetXY,
-                        sequence.getDataType_().isSigned());
+                        sequence.getDataType().isSigned());
                 if (val > maxIntensity[c])
                     maxIntensity[c] = val;
             }
@@ -568,7 +570,7 @@ public class ConnectedComponent extends Detection implements Iterable<Point3i> {
     }
 
     @Override
-    public Iterator<Point3i> iterator() {
+    public @NotNull Iterator<Point3i> iterator() {
         return points.iterator();
     }
 
diff --git a/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponentDescriptor.java b/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponentDescriptor.java
index 6c7a7fd..abe0eeb 100644
--- a/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponentDescriptor.java
+++ b/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponentDescriptor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -20,11 +20,11 @@ package plugins.adufour.connectedcomponents;
 
 import Jama.EigenvalueDecomposition;
 import Jama.Matrix;
-import icy.image.IcyBufferedImage;
-import icy.plugin.abstract_.Plugin;
-import icy.plugin.interface_.PluginBundled;
-import icy.sequence.Sequence;
-import icy.type.DataType;
+import org.bioimageanalysis.icy.common.type.DataType;
+import org.bioimageanalysis.icy.extension.plugin.abstract_.Plugin;
+import org.bioimageanalysis.icy.extension.plugin.interface_.PluginBundled;
+import org.bioimageanalysis.icy.model.image.IcyBufferedImage;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
 import plugins.adufour.blocks.lang.Block;
 import plugins.adufour.blocks.util.VarList;
 import plugins.adufour.quickhull.QuickHull2D;
@@ -389,7 +389,7 @@ public class ConnectedComponentDescriptor extends Plugin implements PluginBundle
             // volume = sum( sqrt[ (x[i] - x[i-1])^2 + (y[i] - y[i-1])^2 ] )
             // area = 0.5 * sum( (x[i-1] * y[i]) - (y[i-1] * x[i]) )
 
-            Point2D p1 = points.get(points.size() - 1), p2;
+            Point2D p1 = points.getLast(), p2;
 
             for (i = 0; i < points.size(); i++) {
                 p2 = points.get(i);
diff --git a/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponents.java b/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponents.java
index baa1be6..f8113aa 100644
--- a/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponents.java
+++ b/src/main/java/plugins/adufour/connectedcomponents/ConnectedComponents.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,56 +18,47 @@
 
 package plugins.adufour.connectedcomponents;
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.vecmath.Point3d;
-import javax.vecmath.Point3i;
-import javax.vecmath.Point4d;
-
-import icy.file.FileUtil;
-import icy.gui.frame.progress.FailedAnnounceFrame;
-import icy.image.IcyBufferedImage;
-import icy.image.colormap.FireColorMap;
-import icy.main.Icy;
-import icy.roi.ROI;
-import icy.sequence.Sequence;
-import icy.sequence.SequenceDataIterator;
-import icy.sequence.VolumetricImage;
-import icy.swimmingPool.SwimmingObject;
-import icy.system.IcyHandledException;
-import icy.type.DataIteratorUtil;
-import icy.type.DataType;
-import icy.type.collection.array.Array1DUtil;
-import icy.util.StringUtil;
-import icy.util.XLSUtil;
-import jxl.write.WritableSheet;
-import jxl.write.WritableWorkbook;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.bioimageanalysis.extension.kernel.roi.roi2d.ROI2DArea;
+import org.bioimageanalysis.extension.kernel.roi.roi3d.ROI3DArea;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.common.collection.array.Array1DUtil;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.common.type.DataIteratorUtil;
+import org.bioimageanalysis.icy.common.type.DataType;
+import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginIcon;
+import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginName;
+import org.bioimageanalysis.icy.gui.frame.progress.FailedAnnounceFrame;
+import org.bioimageanalysis.icy.io.FileUtil;
+import org.bioimageanalysis.icy.io.xls.XLSXUtil;
+import org.bioimageanalysis.icy.model.colormap.FireColorMap;
+import org.bioimageanalysis.icy.model.image.IcyBufferedImage;
+import org.bioimageanalysis.icy.model.roi.ROI;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.model.sequence.SequenceDataIterator;
+import org.bioimageanalysis.icy.model.sequence.VolumetricImage;
+import org.bioimageanalysis.icy.model.swimmingPool.SwimmingObject;
+import org.bioimageanalysis.icy.system.IcyHandledException;
 import plugins.adufour.blocks.lang.Block;
 import plugins.adufour.blocks.util.VarList;
-import plugins.adufour.ezplug.EzGroup;
-import plugins.adufour.ezplug.EzLabel;
-import plugins.adufour.ezplug.EzPlug;
-import plugins.adufour.ezplug.EzVarBoolean;
-import plugins.adufour.ezplug.EzVarEnum;
-import plugins.adufour.ezplug.EzVarFile;
-import plugins.adufour.ezplug.EzVarInteger;
-import plugins.adufour.ezplug.EzVarSequence;
+import plugins.adufour.ezplug.*;
 import plugins.adufour.vars.lang.VarGenericArray;
 import plugins.adufour.vars.lang.VarROIArray;
 import plugins.adufour.vars.lang.VarSequence;
 import plugins.adufour.vars.util.VarException;
-import plugins.kernel.roi.roi2d.ROI2DArea;
-import plugins.kernel.roi.roi3d.ROI3DArea;
 import plugins.nchenouard.spot.DetectionResult;
 import plugins.nchenouard.spot.Spot;
 
+import javax.vecmath.Point3d;
+import javax.vecmath.Point3i;
+import javax.vecmath.Point4d;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+@IcyPluginName("Connected Components")
+@IcyPluginIcon(path = "/icon/Connected_Components.png")
 public class ConnectedComponents extends EzPlug implements Block {
     /**
      * List of extraction methods suitable for the Connected Components plugin
@@ -359,17 +350,18 @@ public class ConnectedComponents extends EzPlug implements Block {
         if (exportExcel.getValue()) {
             int page = 1;
 
-            WritableSheet sheet;
-            final WritableWorkbook workbook;
+            Sheet sheet;
+            final Workbook workbook;
+
+            File f = exportExcelFile.getValue(true);
+            if (!FileUtil.getFileExtension(f.getPath(), false).equalsIgnoreCase("xlsx"))
+                f = new File(f.getPath() + ".xlsx");
 
             try {
-                File f = exportExcelFile.getValue(true);
-                if (!FileUtil.getFileExtension(f.getPath(), false).equalsIgnoreCase("xls"))
-                    f = new File(f.getPath() + ".xls");
-                workbook = XLSUtil.createWorkbook(f);
-                sheet = XLSUtil.createNewPage(workbook, "Page " + page);
+                workbook = XLSXUtil.createWorkbook();
+                sheet = XLSXUtil.createNewPage(workbook, "Page " + page);
             }
-            catch (final Exception e) {
+            catch (final IOException e) {
                 throw new IcyHandledException(e.getMessage());
             }
 
@@ -383,37 +375,37 @@ public class ConnectedComponents extends EzPlug implements Block {
             res += ", Z=" + StringUtil.toStringEx(resolution.z, 5);
             res += ", T=" + StringUtil.toStringEx(resolution.w, 5);
 
-            XLSUtil.setCellString(sheet, 0, 0, s.getName());
-            XLSUtil.setCellString(sheet, 6, 0, res);
-            XLSUtil.setCellString(sheet, 0, 1, "#");
-            XLSUtil.setCellString(sheet, 1, 1, "t");
-            XLSUtil.setCellString(sheet, 2, 1, "x");
-            XLSUtil.setCellString(sheet, 3, 1, "y");
-            XLSUtil.setCellString(sheet, 4, 1, "z");
-            XLSUtil.setCellString(sheet, 5, 1, "perimeter");
-            XLSUtil.setCellString(sheet, 6, 1, "area");
-            XLSUtil.setCellString(sheet, 7, 1, "sphericity");
-            XLSUtil.setCellString(sheet, 8, 1, "major axis");
-            XLSUtil.setCellString(sheet, 9, 1, "minor axis");
-            XLSUtil.setCellString(sheet, 10, 1, "minor Z axis");
-            XLSUtil.setCellString(sheet, 11, 1, "eccentricity");
-            XLSUtil.setCellString(sheet, 12, 1, "hull fill ratio");
-            XLSUtil.setCellString(sheet, 13, 1, "M100");
-            XLSUtil.setCellString(sheet, 14, 1, "M010");
-            XLSUtil.setCellString(sheet, 15, 1, "M001");
-            XLSUtil.setCellString(sheet, 16, 1, "M110");
-            XLSUtil.setCellString(sheet, 17, 1, "M101");
-            XLSUtil.setCellString(sheet, 18, 1, "M011");
-            XLSUtil.setCellString(sheet, 19, 1, "M111");
-            XLSUtil.setCellString(sheet, 20, 1, "M200");
-            XLSUtil.setCellString(sheet, 21, 1, "M020");
-            XLSUtil.setCellString(sheet, 22, 1, "M002");
-            XLSUtil.setCellString(sheet, 23, 1, "M220");
-            XLSUtil.setCellString(sheet, 24, 1, "M202");
-            XLSUtil.setCellString(sheet, 25, 1, "M022");
-            XLSUtil.setCellString(sheet, 26, 1, "M222");
-            XLSUtil.setCellString(sheet, 27, 1, "convex perimeter");
-            XLSUtil.setCellString(sheet, 28, 1, "convex volume");
+            XLSXUtil.setCellString(sheet, 0, 0, s.getName());
+            XLSXUtil.setCellString(sheet, 6, 0, res);
+            XLSXUtil.setCellString(sheet, 0, 1, "#");
+            XLSXUtil.setCellString(sheet, 1, 1, "t");
+            XLSXUtil.setCellString(sheet, 2, 1, "x");
+            XLSXUtil.setCellString(sheet, 3, 1, "y");
+            XLSXUtil.setCellString(sheet, 4, 1, "z");
+            XLSXUtil.setCellString(sheet, 5, 1, "perimeter");
+            XLSXUtil.setCellString(sheet, 6, 1, "area");
+            XLSXUtil.setCellString(sheet, 7, 1, "sphericity");
+            XLSXUtil.setCellString(sheet, 8, 1, "major axis");
+            XLSXUtil.setCellString(sheet, 9, 1, "minor axis");
+            XLSXUtil.setCellString(sheet, 10, 1, "minor Z axis");
+            XLSXUtil.setCellString(sheet, 11, 1, "eccentricity");
+            XLSXUtil.setCellString(sheet, 12, 1, "hull fill ratio");
+            XLSXUtil.setCellString(sheet, 13, 1, "M100");
+            XLSXUtil.setCellString(sheet, 14, 1, "M010");
+            XLSXUtil.setCellString(sheet, 15, 1, "M001");
+            XLSXUtil.setCellString(sheet, 16, 1, "M110");
+            XLSXUtil.setCellString(sheet, 17, 1, "M101");
+            XLSXUtil.setCellString(sheet, 18, 1, "M011");
+            XLSXUtil.setCellString(sheet, 19, 1, "M111");
+            XLSXUtil.setCellString(sheet, 20, 1, "M200");
+            XLSXUtil.setCellString(sheet, 21, 1, "M020");
+            XLSXUtil.setCellString(sheet, 22, 1, "M002");
+            XLSXUtil.setCellString(sheet, 23, 1, "M220");
+            XLSXUtil.setCellString(sheet, 24, 1, "M202");
+            XLSXUtil.setCellString(sheet, 25, 1, "M022");
+            XLSXUtil.setCellString(sheet, 26, 1, "M222");
+            XLSXUtil.setCellString(sheet, 27, 1, "convex perimeter");
+            XLSXUtil.setCellString(sheet, 28, 1, "convex volume");
 
             final ConnectedComponentDescriptor shapeDescriptor = new ConnectedComponentDescriptor();
             int cpt = 2;
@@ -424,68 +416,68 @@ public class ConnectedComponents extends EzPlug implements Block {
                     center.x *= resolution.x;
                     center.y *= resolution.y;
                     center.z *= resolution.z;
-                    XLSUtil.setCellNumber(sheet, 0, cpt, cpt - 1);
-                    XLSUtil.setCellNumber(sheet, 1, cpt, time * resolution.w);
-                    XLSUtil.setCellNumber(sheet, 2, cpt, center.x);
-                    XLSUtil.setCellNumber(sheet, 3, cpt, center.y);
-                    XLSUtil.setCellNumber(sheet, 4, cpt, center.z);
-                    XLSUtil.setCellNumber(sheet, 5, cpt, shapeDescriptor.computePerimeter(cc, null, null));
-                    XLSUtil.setCellNumber(sheet, 6, cpt, cc.getSize() * voxelSize);
-                    XLSUtil.setCellNumber(sheet, 7, cpt, shapeDescriptor.computeSphericity(cc));
+                    XLSXUtil.setCellNumber(sheet, 0, cpt, (double) (cpt - 1));
+                    XLSXUtil.setCellNumber(sheet, 1, cpt, time * resolution.w);
+                    XLSXUtil.setCellNumber(sheet, 2, cpt, center.x);
+                    XLSXUtil.setCellNumber(sheet, 3, cpt, center.y);
+                    XLSXUtil.setCellNumber(sheet, 4, cpt, center.z);
+                    XLSXUtil.setCellNumber(sheet, 5, cpt, shapeDescriptor.computePerimeter(cc, null, null));
+                    XLSXUtil.setCellNumber(sheet, 6, cpt, cc.getSize() * voxelSize);
+                    XLSXUtil.setCellNumber(sheet, 7, cpt, shapeDescriptor.computeSphericity(cc));
                     final double[] radiuses = shapeDescriptor.computeEllipseDimensions(cc);
-                    XLSUtil.setCellNumber(sheet, 8, cpt, radiuses[0]);
-                    XLSUtil.setCellNumber(sheet, 9, cpt, radiuses[1]);
-                    XLSUtil.setCellNumber(sheet, 10, cpt, radiuses[2]);
-                    XLSUtil.setCellNumber(sheet, 11, cpt, shapeDescriptor.computeEccentricity(cc));
+                    XLSXUtil.setCellNumber(sheet, 8, cpt, radiuses[0]);
+                    XLSXUtil.setCellNumber(sheet, 9, cpt, radiuses[1]);
+                    XLSXUtil.setCellNumber(sheet, 10, cpt, radiuses[2]);
+                    XLSXUtil.setCellNumber(sheet, 11, cpt, shapeDescriptor.computeEccentricity(cc));
 
                     final double[] contour_area = shapeDescriptor.computeConvexAreaAndVolume(cc);
-                    XLSUtil.setCellNumber(sheet, 12, cpt, contour_area[1] == 0.0 ? 0.0 : Math.min(1.0, cc.getSize() / contour_area[1]));
-                    XLSUtil.setCellNumber(sheet, 13, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 0, 0));
-                    XLSUtil.setCellNumber(sheet, 14, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 1, 0));
+                    XLSXUtil.setCellNumber(sheet, 12, cpt, contour_area[1] == 0.0 ? 0.0 : Math.min(1.0, cc.getSize() / contour_area[1]));
+                    XLSXUtil.setCellNumber(sheet, 13, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 0, 0));
+                    XLSXUtil.setCellNumber(sheet, 14, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 1, 0));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 15, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 0, 1));
+                        XLSXUtil.setCellNumber(sheet, 15, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 0, 1));
 
-                    XLSUtil.setCellNumber(sheet, 16, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 1, 0));
+                    XLSXUtil.setCellNumber(sheet, 16, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 1, 0));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 17, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 0, 1));
+                        XLSXUtil.setCellNumber(sheet, 17, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 0, 1));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 18, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 1, 1));
+                        XLSXUtil.setCellNumber(sheet, 18, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 1, 1));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 19, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 1, 1));
+                        XLSXUtil.setCellNumber(sheet, 19, cpt, shapeDescriptor.computeGeometricMoment(cc, 1, 1, 1));
 
-                    XLSUtil.setCellNumber(sheet, 20, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 0, 0));
-                    XLSUtil.setCellNumber(sheet, 21, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 2, 0));
+                    XLSXUtil.setCellNumber(sheet, 20, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 0, 0));
+                    XLSXUtil.setCellNumber(sheet, 21, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 2, 0));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 22, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 0, 2));
+                        XLSXUtil.setCellNumber(sheet, 22, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 0, 2));
 
-                    XLSUtil.setCellNumber(sheet, 23, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 2, 0));
+                    XLSXUtil.setCellNumber(sheet, 23, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 2, 0));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 24, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 0, 2));
+                        XLSXUtil.setCellNumber(sheet, 24, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 0, 2));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 25, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 2, 2));
+                        XLSXUtil.setCellNumber(sheet, 25, cpt, shapeDescriptor.computeGeometricMoment(cc, 0, 2, 2));
 
                     if (!is2D)
-                        XLSUtil.setCellNumber(sheet, 26, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 2, 2));
+                        XLSXUtil.setCellNumber(sheet, 26, cpt, shapeDescriptor.computeGeometricMoment(cc, 2, 2, 2));
 
-                    XLSUtil.setCellNumber(sheet, 27, cpt, contour_area[0]);
-                    XLSUtil.setCellNumber(sheet, 28, cpt, contour_area[1]);
+                    XLSXUtil.setCellNumber(sheet, 27, cpt, contour_area[0]);
+                    XLSXUtil.setCellNumber(sheet, 28, cpt, contour_area[1]);
                     cpt++;
                     if (cpt == Short.MAX_VALUE) {
                         page++;
-                        sheet = XLSUtil.createNewPage(workbook, "Page " + page);
+                        sheet = XLSXUtil.createNewPage(workbook, "Page " + page);
                         cpt = 1;
                     }
                 }
 
             try {
-                XLSUtil.saveAndClose(workbook);
+                XLSXUtil.saveAndClose(workbook, f);
             }
             catch (final Exception e) {
                 throw new IcyHandledException(e.getMessage());
@@ -761,7 +753,7 @@ public class ConnectedComponents extends EzPlug implements Block {
             int voxelOffset = 0;
 
             final Object inputData = stack.getImage(z).getDataXY(0);
-            final DataType dataType = stack.getImage(z).getDataType_();
+            final DataType dataType = stack.getImage(z).getDataType();
 
             for (int y = 0; y < height; y++) {
                 onEdgeY = (y == 0 || y == height - 1);
diff --git a/src/main/resources/icon/Connected_Components.png b/src/main/resources/icon/Connected_Components.png
new file mode 100644
index 0000000000000000000000000000000000000000..75d115265fc73272e854d46e26b680d999b78f58
GIT binary patch
literal 7851
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
JPDHLkV1iKuR6qa#

literal 0
HcmV?d00001

-- 
GitLab