org.scijava
scijava-common
diff --git a/src/main/java/net/imagej/ui/swing/SwingColorBar.java b/src/main/java/net/imagej/ui/swing/SwingColorBar.java
index 0bbea6a..80e133f 100644
--- a/src/main/java/net/imagej/ui/swing/SwingColorBar.java
+++ b/src/main/java/net/imagej/ui/swing/SwingColorBar.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/commands/OverlayManager.java b/src/main/java/net/imagej/ui/swing/commands/OverlayManager.java
index 3344cd3..e7619f9 100644
--- a/src/main/java/net/imagej/ui/swing/commands/OverlayManager.java
+++ b/src/main/java/net/imagej/ui/swing/commands/OverlayManager.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/mdi/viewer/SwingMdiImageDisplayViewer.java b/src/main/java/net/imagej/ui/swing/mdi/viewer/SwingMdiImageDisplayViewer.java
index b12630a..90ab9c1 100644
--- a/src/main/java/net/imagej/ui/swing/mdi/viewer/SwingMdiImageDisplayViewer.java
+++ b/src/main/java/net/imagej/ui/swing/mdi/viewer/SwingMdiImageDisplayViewer.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/AbstractJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/AbstractJHotDrawAdapter.java
index 04f1417..ac0dc3c 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/AbstractJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/AbstractJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/AngleJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/AngleJHotDrawAdapter.java
index a4ceaf1..ad9a793 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/AngleJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/AngleJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/BezierPathFunctions.java b/src/main/java/net/imagej/ui/swing/overlay/BezierPathFunctions.java
index 21b5216..c911897 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/BezierPathFunctions.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/BezierPathFunctions.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/DefaultJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/DefaultJHotDrawAdapter.java
index 5240e6a..94e0d1b 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/DefaultJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/DefaultJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/EllipseJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/EllipseJHotDrawAdapter.java
index 19ad2a4..1efeace 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/EllipseJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/EllipseJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/FigureCreatedEvent.java b/src/main/java/net/imagej/ui/swing/overlay/FigureCreatedEvent.java
index c5e8be6..a737b1c 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/FigureCreatedEvent.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/FigureCreatedEvent.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/GeneralPathFigure.java b/src/main/java/net/imagej/ui/swing/overlay/GeneralPathFigure.java
index 7c8a0a3..b563f4a 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/GeneralPathFigure.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/GeneralPathFigure.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/GeneralPathJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/GeneralPathJHotDrawAdapter.java
index 6520f3e..2dbb766 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/GeneralPathJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/GeneralPathJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/IJBezierTool.java b/src/main/java/net/imagej/ui/swing/overlay/IJBezierTool.java
index 5d8d37c..4845e9c 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/IJBezierTool.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/IJBezierTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/IJCreationTool.java b/src/main/java/net/imagej/ui/swing/overlay/IJCreationTool.java
index 6abdd7a..ffb629c 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/IJCreationTool.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/IJCreationTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/IJDelegationSelectionTool.java b/src/main/java/net/imagej/ui/swing/overlay/IJDelegationSelectionTool.java
index b4a1f43..0ac746d 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/IJDelegationSelectionTool.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/IJDelegationSelectionTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/JHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/JHotDrawAdapter.java
index 87bcab9..e1df82b 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/JHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/JHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/JHotDrawService.java b/src/main/java/net/imagej/ui/swing/overlay/JHotDrawService.java
index a9d2916..28e2dd6 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/JHotDrawService.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/JHotDrawService.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/JHotDrawTool.java b/src/main/java/net/imagej/ui/swing/overlay/JHotDrawTool.java
index 90c4de4..9e02b3d 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/JHotDrawTool.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/JHotDrawTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/LineJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/LineJHotDrawAdapter.java
index 408f26e..8739173 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/LineJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/LineJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/PointFigure.java b/src/main/java/net/imagej/ui/swing/overlay/PointFigure.java
index d9692a2..db4e3a0 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/PointFigure.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/PointFigure.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/PointJHotDrawOverlay.java b/src/main/java/net/imagej/ui/swing/overlay/PointJHotDrawOverlay.java
index 9796e9d..2420f3b 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/PointJHotDrawOverlay.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/PointJHotDrawOverlay.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/PolygonFigure.java b/src/main/java/net/imagej/ui/swing/overlay/PolygonFigure.java
index 9fae53c..2ff3455 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/PolygonFigure.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/PolygonFigure.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/PolygonJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/PolygonJHotDrawAdapter.java
index 612abf9..cf19a8e 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/PolygonJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/PolygonJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/PolygonNodeHandle.java b/src/main/java/net/imagej/ui/swing/overlay/PolygonNodeHandle.java
index db5eca4..eaa5acc 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/PolygonNodeHandle.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/PolygonNodeHandle.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/PolylineFigure.java b/src/main/java/net/imagej/ui/swing/overlay/PolylineFigure.java
index f624107..a6af26f 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/PolylineFigure.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/PolylineFigure.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/PolylineJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/PolylineJHotDrawAdapter.java
index d2085e7..c233109 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/PolylineJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/PolylineJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/RectangleJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/RectangleJHotDrawAdapter.java
index 3c8eb36..48b9db7 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/RectangleJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/RectangleJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/SwingOverlayManager.java b/src/main/java/net/imagej/ui/swing/overlay/SwingOverlayManager.java
index 3cbe154..10279ef 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/SwingOverlayManager.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/SwingOverlayManager.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/ThresholdFigure.java b/src/main/java/net/imagej/ui/swing/overlay/ThresholdFigure.java
index f52cfc3..98c0275 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/ThresholdFigure.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/ThresholdFigure.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/ThresholdJHotDrawAdapter.java b/src/main/java/net/imagej/ui/swing/overlay/ThresholdJHotDrawAdapter.java
index d98a1ec..b064aef 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/ThresholdJHotDrawAdapter.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/ThresholdJHotDrawAdapter.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/overlay/ToolDelegator.java b/src/main/java/net/imagej/ui/swing/overlay/ToolDelegator.java
index 7aa9756..7873717 100644
--- a/src/main/java/net/imagej/ui/swing/overlay/ToolDelegator.java
+++ b/src/main/java/net/imagej/ui/swing/overlay/ToolDelegator.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/sdi/viewer/SwingSdiImageDisplayViewer.java b/src/main/java/net/imagej/ui/swing/sdi/viewer/SwingSdiImageDisplayViewer.java
index d3f7ee1..9c0bb8f 100644
--- a/src/main/java/net/imagej/ui/swing/sdi/viewer/SwingSdiImageDisplayViewer.java
+++ b/src/main/java/net/imagej/ui/swing/sdi/viewer/SwingSdiImageDisplayViewer.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingAngleTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingAngleTool.java
index 6b1d1aa..6c3827d 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingAngleTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingAngleTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingEllipseTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingEllipseTool.java
index 1d92389..e56d0f1 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingEllipseTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingEllipseTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingLineTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingLineTool.java
index d692f5c..3f5c38a 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingLineTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingLineTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingPointTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingPointTool.java
index 5d8f755..842c409 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingPointTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingPointTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingPolygonTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingPolygonTool.java
index d9e363f..a69f1dc 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingPolygonTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingPolygonTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingPolylineTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingPolylineTool.java
index 5399386..5bb6231 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingPolylineTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingPolylineTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingRectangleTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingRectangleTool.java
index 20ec08e..5dcef17 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingRectangleTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingRectangleTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/tools/SwingTextTool.java b/src/main/java/net/imagej/ui/swing/tools/SwingTextTool.java
index 0e1125f..afdf788 100644
--- a/src/main/java/net/imagej/ui/swing/tools/SwingTextTool.java
+++ b/src/main/java/net/imagej/ui/swing/tools/SwingTextTool.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/ConflictDialog.java b/src/main/java/net/imagej/ui/swing/updater/ConflictDialog.java
index aba8130..efd7886 100644
--- a/src/main/java/net/imagej/ui/swing/updater/ConflictDialog.java
+++ b/src/main/java/net/imagej/ui/swing/updater/ConflictDialog.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/DiffFile.java b/src/main/java/net/imagej/ui/swing/updater/DiffFile.java
index db24808..6212b58 100644
--- a/src/main/java/net/imagej/ui/swing/updater/DiffFile.java
+++ b/src/main/java/net/imagej/ui/swing/updater/DiffFile.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/DiffView.java b/src/main/java/net/imagej/ui/swing/updater/DiffView.java
index 9d60212..8398604 100644
--- a/src/main/java/net/imagej/ui/swing/updater/DiffView.java
+++ b/src/main/java/net/imagej/ui/swing/updater/DiffView.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/FileDetails.java b/src/main/java/net/imagej/ui/swing/updater/FileDetails.java
index 61cbca2..1053b12 100644
--- a/src/main/java/net/imagej/ui/swing/updater/FileDetails.java
+++ b/src/main/java/net/imagej/ui/swing/updater/FileDetails.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/FileTable.java b/src/main/java/net/imagej/ui/swing/updater/FileTable.java
index 1e47a79..0a25870 100644
--- a/src/main/java/net/imagej/ui/swing/updater/FileTable.java
+++ b/src/main/java/net/imagej/ui/swing/updater/FileTable.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/ImageJUpdater.java b/src/main/java/net/imagej/ui/swing/updater/ImageJUpdater.java
index 39cd189..2a1cdbd 100644
--- a/src/main/java/net/imagej/ui/swing/updater/ImageJUpdater.java
+++ b/src/main/java/net/imagej/ui/swing/updater/ImageJUpdater.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -29,18 +29,16 @@
package net.imagej.ui.swing.updater;
+import java.awt.EventQueue;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.Authenticator;
import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
import java.net.URL;
-import java.net.URLClassLoader;
import java.net.URLConnection;
import java.net.UnknownHostException;
-import java.util.ArrayList;
import java.util.List;
import net.imagej.ui.swing.updater.ViewOptions.Option;
@@ -48,8 +46,8 @@
import net.imagej.updater.Conflicts.Conflict;
import net.imagej.updater.util.*;
+import org.scijava.Context;
import org.scijava.app.StatusService;
-import org.scijava.command.CommandService;
import org.scijava.event.ContextDisposingEvent;
import org.scijava.event.EventHandler;
import org.scijava.log.LogService;
@@ -59,37 +57,32 @@
import org.scijava.plugin.Plugin;
import org.scijava.util.AppUtils;
-import javax.swing.*;
-
/**
* The Updater. As a command.
- *
- * Incidentally, this class can be used as an out-of-ImageJ entry point to the
- * updater, as it does not *require* a StatusService to run.
- *
+ *
* @author Johannes Schindelin
*/
@Plugin(type = UpdaterUI.class, menu = { @Menu(label = "Help"),
@Menu(label = "Update...") })
public class ImageJUpdater implements UpdaterUI {
+
private UpdaterFrame main;
- @Parameter
+ @Parameter(required = false)
+ private Context context;
+
+ @Parameter(required = false)
private StatusService statusService;
- @Parameter
+ @Parameter(required = false)
private LogService log;
- @Parameter
+ @Parameter(required = false)
private UploaderService uploaderService;
- @Parameter
- private CommandService commandService;
-
- private final static String UPDATER_UPDATING_THREAD_NAME = "Updating the Updater itself!";
-
@Override
public void run() {
+ new LauncherMigrator(context).checkLaunchStatus();
if (errorIfDebian()) return;
@@ -99,14 +92,12 @@ public void run() {
if (errorIfNetworkInaccessible(log)) return;
- String imagejDirProperty = System.getProperty("imagej.dir");
- final File imagejRoot = imagejDirProperty != null ? new File(imagejDirProperty) :
- AppUtils.getBaseDirectory("ij.dir", FilesCollection.class, "updater");
- final FilesCollection files = new FilesCollection(log, imagejRoot);
+ final File appDir = getAppDirectory();
+ final FilesCollection files = new FilesCollection(log, appDir);
UpdaterUserInterface.set(new SwingUserInterface(log, statusService));
- if (!areWeUpdatingTheUpdater() && new File(imagejRoot, "update").exists()) {
+ if (new File(appDir, "update").exists()) {
if (!UpdaterUserInterface.get().promptYesNo("It is suggested that you restart ImageJ, then continue the update.\n"
+ "Alternately, you can attempt to continue the upgrade without\n"
+ "restarting, but ImageJ might crash.\n\n"
@@ -168,56 +159,6 @@ protected void updateConflictList() {
return;
}
- if (!areWeUpdatingTheUpdater() && Installer.isTheUpdaterUpdateable(files, commandService)) {
- try {
- // download just the updater
- Installer.updateTheUpdater(files, main.getProgress("Installing the updater..."), commandService);
- }
- catch (final UpdateCanceledException e) {
- main.error("Canceled");
- return;
- }
- catch (final IOException e) {
- main.error("Installer failed: " + e);
- return;
- }
-
- // make a class path using the updated files
- final List classPath = new ArrayList<>();
- for (FileObject component : Installer.getUpdaterFiles(files, commandService, false)) {
- final File updated = files.prefixUpdate(component.getFilename(false));
- if (updated.exists()) try {
- classPath.add(updated.toURI().toURL());
- continue;
- } catch (MalformedURLException e) {
- log.error(e);
- }
- final String name = component.getLocalFilename(false);
- File file = files.prefix(name);
- try {
- classPath.add(file.toURI().toURL());
- } catch (MalformedURLException e) {
- log.error(e);
- }
- }
- try {
- log.info("Trying to install and execute the new updater");
- final URL[] urls = classPath.toArray(new URL[classPath.size()]);
- URLClassLoader remoteClassLoader = new URLClassLoader(urls, getClass().getClassLoader().getParent());
- Class> runnable = remoteClassLoader.loadClass(ImageJUpdater.class.getName());
- final Thread thread = new Thread((Runnable)runnable.newInstance());
- thread.setName(UPDATER_UPDATING_THREAD_NAME);
- thread.start();
- thread.join();
- return;
- } catch (Throwable t) {
- log.error(t);
- }
-
- main.info("Please restart ImageJ and call Help>Update to continue with the update");
- return;
- }
-
try {
final String missingUploaders = main.files.protocolsMissingUploaders(main.getUploaderService(), main.getProgress(null));
if (missingUploaders != null) {
@@ -245,6 +186,12 @@ protected void updateConflictList() {
main.updateFilesTable();
}
+ static File getAppDirectory() {
+ String imagejDirProperty = System.getProperty("imagej.dir");
+ return imagejDirProperty != null ? new File(imagejDirProperty) :
+ AppUtils.getBaseDirectory("ij.dir", FilesCollection.class, "updater");
+ }
+
private void refreshUpdateSites(FilesCollection files)
throws InterruptedException, InvocationTargetException
{
@@ -252,7 +199,7 @@ private void refreshUpdateSites(FilesCollection files)
changes = AvailableSites.initializeAndAddSites(files, (Logger) log);
if(ReviewSiteURLsDialog.shouldBeDisplayed(changes)) {
ReviewSiteURLsDialog dialog = new ReviewSiteURLsDialog(main, changes);
- SwingUtilities.invokeAndWait(() -> dialog.setVisible(true));
+ EventQueue.invokeAndWait(() -> dialog.setVisible(true));
if(dialog.isOkPressed())
AvailableSites.applySitesURLUpdates(files, changes);
}
@@ -414,11 +361,8 @@ protected static boolean moveOutOfTheWay(final File file) {
return file.renameTo(backup);
}
- private boolean areWeUpdatingTheUpdater() {
- return UPDATER_UPDATING_THREAD_NAME.equals(Thread.currentThread().getName());
- }
-
public static void main(String[] args) {
new ImageJUpdater().run();
}
+
}
diff --git a/src/main/java/net/imagej/ui/swing/updater/LauncherMigrator.java b/src/main/java/net/imagej/ui/swing/updater/LauncherMigrator.java
new file mode 100644
index 0000000..765f9b9
--- /dev/null
+++ b/src/main/java/net/imagej/ui/swing/updater/LauncherMigrator.java
@@ -0,0 +1,567 @@
+/*
+ * #%L
+ * ImageJ software for multidimensional image processing and analysis.
+ * %%
+ * Copyright (C) 2009 - 2024 ImageJ developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+package net.imagej.ui.swing.updater;
+
+import net.imagej.updater.util.UpdaterUtil;
+import org.scijava.Context;
+import org.scijava.app.AppService;
+import org.scijava.launcher.Java;
+import org.scijava.launcher.Versions;
+import org.scijava.log.LogService;
+import org.scijava.log.Logger;
+import org.scijava.ui.ApplicationFrame;
+import org.scijava.ui.UIService;
+import org.scijava.ui.UserInterface;
+import org.scijava.widget.UIComponent;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+import javax.swing.UIManager;
+import java.awt.Window;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.prefs.Preferences;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * Absurdly complex logic for helping users transition
+ * safely from the old ImageJ launcher to the new one.
+ *
+ * @author Curtis Rueden
+ */
+class LauncherMigrator {
+
+ private static final List ARM32 = Arrays.asList("aarch32", "arm32");
+ private static final List ARM64 = Arrays.asList("aarch64", "arm64");
+ private static final List X32 =
+ Arrays.asList("i386", "i486", "i586", "i686", "x86-32", "x86_32", "x86");
+ private static final List X64 =
+ Arrays.asList("amd64", "x86-64", "x86_64", "x64");
+ private static final boolean OS_WIN, OS_MACOS, OS_LINUX;
+ private static final String OS, ARCH;
+
+ static {
+ OS = System.getProperty("os.name");
+ OS_WIN = OS.toLowerCase().contains("windows");
+ OS_MACOS = OS.toLowerCase().contains("mac");
+ OS_LINUX = OS.toLowerCase().contains("linux");
+ String osArch = System.getProperty("os.arch").toLowerCase();
+ if (ARM32.contains(osArch)) ARCH = "arm32";
+ else if (ARM64.contains(osArch)) ARCH = "arm64";
+ else if (X32.contains(osArch)) ARCH = "x32";
+ else if (X64.contains(osArch)) ARCH = "x64";
+ else ARCH = osArch;
+ }
+
+ private AppService appService;
+ private UIService uiService;
+ private Logger log;
+
+ LauncherMigrator(Context ctx) {
+ if (ctx == null) return;
+ appService = ctx.getService(AppService.class);
+ uiService = ctx.getService(UIService.class);
+ log = ctx.getService(LogService.class);
+ }
+
+ /**
+ * Figures out what's going on with the application's launch situation.
+ *
+ * - If launched with the old ImageJ launcher, call
+ * {@link #switchToNewLauncher()}.
+ * - If launched with the new Jaunch launcher, call
+ * {@link #migrateShortcuts()} and {@link #migrateUpdateSite()}.
+ * - If launched in some other creative way, do nothing.
+ *
+ */
+ void checkLaunchStatus() {
+ // Check whether *either* launcher (old or new) launched the app.
+ // Both launchers set one of these telltale properties.
+ boolean launcherUsed =
+ System.getProperty("ij.executable") != null ||
+ System.getProperty("fiji.executable") != null;
+ if (!launcherUsed) return; // Program was launched in some creative way.
+
+ // Check if the old launcher launched the app.
+ // The old launcher does not set the scijava.app.name property.
+ boolean oldLauncherUsed = System.getProperty("scijava.app.name") == null;
+ if (oldLauncherUsed) switchToNewLauncher();
+ else {
+ migrateShortcuts();
+ migrateUpdateSite();
+ }
+ }
+
+ /**
+ * Updates platform-specific shortcuts to reference the new launcher,
+ * including {@code .desktop} files on Linux.
+ *
+ * The macOS-specific {@code Contents/Info.plist} is handled separately
+ * by the Updater, as part of the switch to the new update site; see
+ * {@link #migrateUpdateSite()}.
+ *
+ *
+ * Windows users are advised to update their shortcuts by hand, because:
+ * A) we don't know where the user put their Fiji shortcuts—they
+ * could be in the Start menu, on the desktop, or elsewhere and pinned
+ * to the taskbar; and B) the .lnk file format is an opaque binary
+ * format and I'm not going to code up something to hack it just for
+ * this transitional migration code that will be obsolete in a few months.
+ *
+ *
+ * Finally, old launchers are renamed with {@code .backup} extension in
+ * case there are any missed shortcuts, so that launch fails fast at the
+ * OS level rather than potentially exploding at the application level.
+ *
+ */
+ private void migrateShortcuts() {
+ // If no old launchers are present, assume we already did this.
+ // FIXME: Which launcher(s) should we look for? All platforms? Or current only?
+
+ // Fix links within Linux .desktop files.
+ // ~/.local/share/applications
+ // ~/.local/share/applications/wine/Programs
+ // /usr/share/applications
+ // /usr/local/share/applications
+ // /var/lib/flatpak/exports/share/applications
+ // START HERE: Scan all .desktop files? Or only ImageJ2.desktop and Fiji.desktop? Or...?
+ // Completely rewrite them? By calling what code? Can we reuse the code that generated
+ // them in the first place? Where is that code? The only code I could find that generates
+ // one of these files is fiji/fiji/scripts/Plugins/Utilities/Create_Desktop_Icon.bsh,
+ // but it's outdated. So what is making these files these days??
+
+ if (OS_WIN) {
+ // FIXME: Warn user to update any shortcuts!
+ }
+
+ //
+ }
+
+ /**
+ * Checks whether the application is running with a
+ * sufficient Java version, and if so, transitions it to the new core update site.
+ */
+ private void migrateUpdateSite() {
+ throw new UnsupportedOperationException("migrateUpdateSite unimplemented"); //FIXME
+ }
+
+ /**
+ * Checks whether this installation has the new launcher available, and if so,
+ * clues in the user, informing them about the pros and cons of switching.
+ * Then, if they should elect to switch, upgrades the managed Java to the
+ * recommended one and finally relaunches with the new launcher.
+ */
+ private void switchToNewLauncher() {
+ // Check whether the user has silenced the launcher upgrade prompt.
+ String prefKey = "skipLauncherUpgradePrompt";
+ Preferences prefs = Preferences.userNodeForPackage(getClass());
+ boolean skipPrompt = prefs.getBoolean(prefKey, false);
+ if (skipPrompt) {
+ // User previously said to "never ask again".
+ if (log != null) log.debug("Skipping launcher upgrade due to user preference");
+ return;
+ }
+
+ // Define the title of the application.
+ // Note: I wanted to use the AppService for this.
+ // But the net.imagej.app.TopLevelImageJApp in net.imagej:imagej
+ // has higher priority than the sc.fiji.app.FijiApp in sc.fiji:fiji,
+ // so appService.getApp().getTitle() does not yield the needed string.
+ // In practice, the only launcher migration path we are supporting
+ // with this code is ImageJ- -> fiji-, nothing else.
+ String appTitle = "Fiji";
+
+ // Discern the application base directory.
+ File appDir = appService == null ?
+ ImageJUpdater.getAppDirectory() :
+ appService.getApp().getBaseDirectory();
+ if (appDir == null) {
+ if (log != null) log.debug("Cannot glean base directory");
+ return;
+ }
+ appDir = appDir.getAbsoluteFile();
+ String appSlug = appTitle.toLowerCase();
+ File configDir = appDir.toPath().resolve("config").resolve("jaunch").toFile();
+
+ // Test whether the new launcher is likely to work on this system.
+ String nljv;
+ try {
+ nljv = probeJavaVersion(appDir, configDir, appSlug);
+ if (log != null) log.debug("Java from new launcher BEFORE: " + nljv);
+ }
+ catch (IOException exc) {
+ // Something bad happened invoking the new launcher.
+ // We inform the user and ask for a bug report, then give up.
+ askForBugReport(log, appTitle, appSlug, exc);
+ return;
+ }
+ catch (UnsupportedOperationException exc) {
+ // No new executable launcher is available for this platform.
+ // We give up, because there is nothing to switch over to.
+ if (log != null) log.debug(exc);
+ return;
+ }
+
+ // OK, we've gotten far enough that it's time to ask the
+ // user whether they want to upgrade to the new launcher.
+
+ String message = "" +
+ "" +
+ "✨" +
+ " Heads up: " + appTitle + " is receiving some major updates under the hood! " +
+ "✨" +
+ "
You are currently running the stable version of " + appTitle +
+ ", but you now have the option to switch
to the future version. " +
+ "To help you decide, here is a table summarizing the differences:
" +
+ "
" +
+ "Feature | " + appTitle + " stable | " + appTitle + " Future |
" +
+ "Stability | More | Less |
" +
+ "Java version | OpenJDK 8 | OpenJDK 21 |
" +
+ "Launcher | ImageJ Launcher (deprecated) | Jaunch |
" +
+ "Executable | ImageJ-*(.exe) | fiji-*-*(.exe) |
" +
+ "Core update site(s) | ImageJ+Fiji+Java-8 | sites.imagej.net/Fiji |
" +
+ "Apple silicon? | Emulated/x86 mode | Native! |
" +
+ "Receives updates? | Security only | Latest features |
" +
+ "Minimum Windows | Windows XP | Windows 10 |
" +
+ "Minimum macOS | Mac OS X 10.8 'Mountain Lion' | macOS 11 'Big Sur' |
" +
+ "Minimum Ubuntu | Ubuntu 12.04 'Precise Pangolin' | Ubuntu 22.04 'Jammy Jellyfish' |
" +
+ "Java 3D version | 1.6.0-scijava-2 (buggier) | 1.7.x (less buggy) |
" +
+ "ImgLib2 version | 6.1.0 (released 2023-03-07) | 7.1.2 (released 2024-09-03) |
" +
+ "
" +
+ "In short: updating to Future will let you continue receiving updates, " +
+ "but because it is still
new and less well tested, it also " +
+ "might break your " + appTitle + " installation or favorite plugins.
" +
+ "
How would you like to proceed?";
+
+ int optionType = JOptionPane.DEFAULT_OPTION;
+ int messageType = JOptionPane.QUESTION_MESSAGE;
+ ImageIcon icon = new ImageIcon(appDir.toPath()
+ .resolve("images").resolve("icon.png").toString());
+ int w = icon.getIconWidth();
+ int maxWidth = 120;
+ if (w > maxWidth) {
+ icon = new ImageIcon(icon.getImage().getScaledInstance(
+ maxWidth, icon.getIconHeight() * maxWidth / w,
+ java.awt.Image.SCALE_SMOOTH));
+ }
+ String yes = "Update to Future!
※\\(^o^)/※";
+ String no = "Keep stable for now
⊹╰(~ʟ~)╯⊹";
+ String never = "Stable, and never ask again
୧/0益0\\୨";
+ Object[] options = {yes, no, never};
+ Window parent = getApplicationWindow();
+ int rval = JOptionPane.showOptionDialog(parent, message,
+ appTitle, optionType, messageType, icon, options, no);
+ if (rval != 0) {
+ // User did not opt in to the launcher upgrade.
+ if (rval == 2) prefs.putBoolean(prefKey, true); // never ask again!
+ return;
+ }
+
+ // Here, the user has agreed to switch to the new launcher. At this point
+ // we need to be very careful. Users on Apple silicon hardware are likely
+ // to be running with Rosetta (x86 emulation mode) rather than in native
+ // ARM64 mode. As such, they probably do not have *any* ARM64 version of
+ // Java installed, not even Java 8, much less Java 21+.
+ //
+ // Therefore, we are going to trigger the new app-launcher's Java upgrade
+ // logic now, rather than relying on it to trigger conditionally upon
+ // restart with the new launcher -- because that restart could potentially
+ // fail due to lack of available Java installations, especially on macOS.
+ // In order to trigger it successfully, we need to set various properties:
+
+ File appConfigFile = new File(configDir, appSlug + ".toml");
+ List lines;
+ try {
+ lines = Files.readAllLines(appConfigFile.toPath());
+ }
+ catch (IOException exc) {
+ log.debug(exc);
+ // Couldn't read from the config file.
+ lines = new ArrayList<>();
+ }
+
+ setPropertyIfNull("scijava.app.name", appTitle);
+ setPropertyIfNull("scijava.app.directory", appDir.getPath());
+
+ Path splashImage = appDir.toPath().resolve("images").resolve("icon.png");
+ setPropertyIfNull("scijava.app.splash-image", splashImage.toString());
+
+ extractAndSetProperty("scijava.app.java-links", lines,
+ "https://downloads.imagej.net/java/jdk-urls.txt");
+ extractAndSetProperty("scijava.app.java-version-minimum", lines, "8");
+ extractAndSetProperty("scijava.app.java-version-recommended", lines, "21");
+ extractAndSetProperty("scijava.app.config-file", lines,
+ new File(configDir, appSlug + ".cfg").getPath());
+
+ String platform = UpdaterUtil.getPlatform();
+ // FIXME: I think the macOS platform will be wrong here. It needs -arm64 suffix!
+ setPropertyIfNull("scijava.app.java-platform", platform);
+ setPropertyIfNull("scijava.app.java-root",
+ appDir.toPath().resolve("java").resolve(platform).toString());
+
+ // Now that the properties are set, we can decide whether to upgrade Java.
+ if (nljv == null || Versions.compare(nljv, Java.recommendedVersion()) < 0) {
+ // The new launcher did not find a good-enough Java in our test above,
+ // so we now ask the app-launcher to download and install such a Java.
+ Java.upgrade();
+
+ // And now we test whether the new launcher finds the new Java.
+ try {
+ nljv = probeJavaVersion(appDir, configDir, appSlug);
+ if (log != null) log.debug("Java from new launcher AFTER: " + nljv);
+ }
+ catch (IOException | UnsupportedOperationException exc) {
+ // Something bad happened invoking the new launcher. This is especially
+ // bad because it worked before running the Java upgrade, but now fails.
+ // Bummer. We inform the user and ask for a bug report, then give up.
+ askForBugReport(log, appTitle, appSlug, exc);
+ return;
+ }
+
+ if (nljv == null || Versions.compare(nljv, Java.recommendedVersion()) < 0) {
+ // The new launcher is not using a good-enough Java after upgrading!
+ if (log != null) {
+ Path cfgPath = appDir.toPath().resolve(
+ Paths.get("config", "jaunch", appSlug + ".cfg"));
+ log.warn("Congratulations on upgrading Java.\n\tUnfortunately, " +
+ "the Java version chosen by the new launcher after the upgrade " +
+ "is " + nljv + ", which is still less than the recommended Java " +
+ "version of " + Java.recommendedVersion() + ".\n\tThis should not " +
+ "be the case of course; it seems to be a bug.\n\tWould you please " +
+ "visit https://forum.image.sc/ and report this problem?\n\tClick " +
+ "'New Topic', choose 'Usage & Issues' category, and use tag '" +
+ appSlug + "'.\n\tTo fix it locally for now, you can try editing the " +
+ cfgPath + " file by hand to point to a newer Java installation.");
+ }
+ return;
+ }
+ }
+
+ // All looks good! We can finally relaunch safely with the new launcher.
+ File exeFile = exeFile(appSlug, appDir);
+ try {
+ Process p = new ProcessBuilder(exeFile.getPath()).start();
+ boolean terminated = p.waitFor(500, TimeUnit.MILLISECONDS);
+ if (terminated || !p.isAlive()) {
+ askForBugReport(log, appTitle, appSlug,
+ new RuntimeException("New launcher terminated unexpectedly"));
+ return;
+ }
+ // New process seems to be up and running; we are done. Whew!
+ System.exit(0);
+ }
+ catch (IOException | InterruptedException exc) {
+ askForBugReport(log, appTitle, appSlug, exc);
+ }
+ }
+
+ /** Implores the user to report a bug relating to new launcher switch-over. */
+ private void askForBugReport(
+ Logger log, String appTitle, String appSlug, Exception exc)
+ {
+ if (log == null) return;
+ log.error("Argh! " + appTitle + "'s fancy new launcher is not " +
+ "working on your system! It might be a bug in the new launcher, " +
+ "or your operating system may be too old to support it. Would you " +
+ "please visit https://forum.image.sc/ and report this problem? " +
+ "Click 'New Topic', choose 'Usage & Issues' category, and use tag '" +
+ appSlug + "'. Please copy+paste the technical information below " +
+ "into your report. Thank you!\n\n" +
+ "* os.name=" + System.getProperty("os.name") + "\n" +
+ "* os.arch=" + System.getProperty("os.arch") + "\n" +
+ "* os.version=" + System.getProperty("os.version") + "\n", exc);
+ }
+
+ /**
+ * Invokes the new native launcher, to make sure all is working as intended.
+ *
+ * @return
+ * The version of Java discovered and used by the native launcher, or else
+ * {@code null} if either no valid Java installation is discovered or the
+ * discovered installation emitted no {@code java.version} property value.
+ * @throws IOException
+ * If executing the native launcher or reading its output fails.
+ * @throws UnsupportedOperationException
+ * If no executable native launcher is available for this system platform.
+ */
+ private static String probeJavaVersion(
+ File appDir, File configDir, String appPrefix) throws IOException
+ {
+ // 1. Find and validate the new launcher and helper files.
+
+ File exeFile = exeFile(appPrefix, appDir);
+ if (!configDir.isDirectory()) {
+ throw new UnsupportedOperationException("Launcher config directory is missing: " + configDir);
+ }
+ File propsClass = new File(configDir, "Props.class");
+ if (!propsClass.isFile()) {
+ throw new UnsupportedOperationException("Launcher helper program is missing: " + propsClass);
+ }
+
+ // 2. Run it.
+
+ List output;
+ int exitCode;
+ try {
+ Process p = new ProcessBuilder(exeFile.getPath(),
+ "-Djava.class.path=" + configDir.getPath(), "--main-class", "Props")
+ .redirectErrorStream(true).start();
+ output = collectProcessOutput(p);
+ exitCode = p.exitValue();
+ }
+ catch (InterruptedException exc) {
+ throw new IOException(exc);
+ }
+
+ // 3. Analyze the output.
+
+ String noJavas = "No matching Java installations found.";
+ if (!output.isEmpty() && output.get(0).startsWith(noJavas)) return null;
+
+ // Note: We check the exit code below *after* detecting the lack of Java
+ // installations, because in the above case, that exit code is also non-zero
+ // (20 as of this writing), and we want to return -1, not throw IOException.
+
+ if (exitCode != 0) {
+ throw new IOException("Launcher exited with non-zero value: " + exitCode);
+ }
+
+ String propKey = "java.version=";
+ return output.stream()
+ .filter(line -> line.startsWith(propKey))
+ .map(line -> line.substring(propKey.length()))
+ .findFirst().orElse(null);
+ }
+
+ private static File exeFile(String appPrefix, File appDir) {
+ // Determine the right executable path for the new launcher.
+ String exe;
+ if (OS_WIN) exe = appPrefix + "-windows-" + ARCH + ".exe";
+ else if (OS_MACOS) exe = "Contents/MacOS/" + appPrefix + "-macos-" + ARCH;
+ else if (OS_LINUX) exe = appPrefix + "-linux-" + ARCH;
+ else throw new UnsupportedOperationException("Unsupported OS: " + OS);
+
+ // Do some sanity checks to make sure we can actually run it.
+ File exeFile = new File(appDir, exe);
+ if (!exeFile.isFile()) {
+ throw new UnsupportedOperationException("Launcher is missing: " + exe);
+ }
+ if (!exeFile.canExecute()) {
+ // Weird -- program is not executable like it should be. Try to fix it.
+ //noinspection ResultOfMethodCallIgnored
+ exeFile.setExecutable(true);
+ }
+ if (!exeFile.canExecute()) {
+ throw new UnsupportedOperationException("Launcher is not executable: " + exeFile);
+ }
+
+ return exeFile;
+ }
+
+ private static void setPropertyIfNull(String name, String value) {
+ if (System.getProperty(name) == null) System.setProperty(name, value);
+ }
+
+ private static void extractAndSetProperty(
+ String name,
+ List lines,
+ String fallbackValue)
+ {
+ // No, the following replacement does not escape all problematic regex
+ // characters. But the properties we're working with here are only
+ // alphameric with dot separators, so it's OK. Hooray for pragmatism!
+ String escaped = name.replaceAll("\\.", "\\\\.");
+ Pattern p = Pattern.compile(".*'-D" + escaped + "=['\"]?(.*?)['\"]?,$");
+ String value = fallbackValue;
+ for (String line : lines) {
+ Matcher m = p.matcher(line);
+ if (m.matches()) {
+ value = m.group(1);
+ break;
+ }
+ }
+ if (value != null) setPropertyIfNull(name, value);
+ }
+
+ /** Annoying code to collect stdout lines from a short-running process. */
+ private static List collectProcessOutput(Process p)
+ throws IOException, InterruptedException
+ {
+ boolean completed = p.waitFor(5, TimeUnit.SECONDS);
+ p.exitValue();
+ if (!completed) {
+ p.destroyForcibly();
+ throw new IOException("Process took too long to complete.");
+ }
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
+ return reader.lines().collect(Collectors.toList());
+ }
+ }
+
+ /** Annoying code to discern the AWT/Swing main application frame, if any. */
+ private Window getApplicationWindow() {
+ if (uiService == null) return null;
+ return uiService.getVisibleUIs().stream()
+ .map(this::getApplicationWindow)
+ .filter(Objects::nonNull)
+ .findFirst().orElse(null);
+ }
+
+ private Window getApplicationWindow(UserInterface ui) {
+ ApplicationFrame appFrame = ui.getApplicationFrame();
+ if (appFrame instanceof Window) return (Window) appFrame;
+ if (appFrame instanceof UIComponent) {
+ Object component = ((UIComponent>) appFrame).getComponent();
+ if (component instanceof Window) return (Window) component;
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/net/imagej/ui/swing/updater/ProgressDialog.java b/src/main/java/net/imagej/ui/swing/updater/ProgressDialog.java
index 16421ae..e80aff0 100644
--- a/src/main/java/net/imagej/ui/swing/updater/ProgressDialog.java
+++ b/src/main/java/net/imagej/ui/swing/updater/ProgressDialog.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/ResolveDependencies.java b/src/main/java/net/imagej/ui/swing/updater/ResolveDependencies.java
index 929fa5d..0de20cf 100644
--- a/src/main/java/net/imagej/ui/swing/updater/ResolveDependencies.java
+++ b/src/main/java/net/imagej/ui/swing/updater/ResolveDependencies.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialog.java b/src/main/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialog.java
index aa8e713..691b9fe 100644
--- a/src/main/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialog.java
+++ b/src/main/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialog.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/SitesDialog.java b/src/main/java/net/imagej/ui/swing/updater/SitesDialog.java
index 61eaeb5..7c702b0 100644
--- a/src/main/java/net/imagej/ui/swing/updater/SitesDialog.java
+++ b/src/main/java/net/imagej/ui/swing/updater/SitesDialog.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/SwingAuthenticator.java b/src/main/java/net/imagej/ui/swing/updater/SwingAuthenticator.java
index c0c1c3d..ae1379a 100644
--- a/src/main/java/net/imagej/ui/swing/updater/SwingAuthenticator.java
+++ b/src/main/java/net/imagej/ui/swing/updater/SwingAuthenticator.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/SwingTools.java b/src/main/java/net/imagej/ui/swing/updater/SwingTools.java
index 67d6786..ef201f4 100644
--- a/src/main/java/net/imagej/ui/swing/updater/SwingTools.java
+++ b/src/main/java/net/imagej/ui/swing/updater/SwingTools.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/SwingUserInterface.java b/src/main/java/net/imagej/ui/swing/updater/SwingUserInterface.java
index 9b07809..9face5f 100644
--- a/src/main/java/net/imagej/ui/swing/updater/SwingUserInterface.java
+++ b/src/main/java/net/imagej/ui/swing/updater/SwingUserInterface.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/updater/UpdaterFrame.java b/src/main/java/net/imagej/ui/swing/updater/UpdaterFrame.java
index b118d4f..7d210fd 100644
--- a/src/main/java/net/imagej/ui/swing/updater/UpdaterFrame.java
+++ b/src/main/java/net/imagej/ui/swing/updater/UpdaterFrame.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -357,7 +357,7 @@ public void run() {
upload();
}
catch (final InstantiationException e) {
- log.error(e);
+ if (log != null) log.error(e);
error("Could not upload (possibly unknown protocol)");
}
}
@@ -395,7 +395,7 @@ public void setVisible(final boolean visible) {
} catch (final InterruptedException e) {
// ignore
} catch (final InvocationTargetException e) {
- log.error(e);
+ if (log != null) log.error(e);
}
return;
}
@@ -606,7 +606,7 @@ public void install() {
installer.done();
}
catch (final Exception e) {
- log.error(e);
+ if (log != null) log.error(e);
// TODO: remove "update/" directory
error("Installer failed: " + e);
installer.done();
diff --git a/src/main/java/net/imagej/ui/swing/updater/ViewOptions.java b/src/main/java/net/imagej/ui/swing/updater/ViewOptions.java
index dfcd007..15231ab 100644
--- a/src/main/java/net/imagej/ui/swing/updater/ViewOptions.java
+++ b/src/main/java/net/imagej/ui/swing/updater/ViewOptions.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/viewer/image/AbstractSwingImageDisplayViewer.java b/src/main/java/net/imagej/ui/swing/viewer/image/AbstractSwingImageDisplayViewer.java
index 35070cd..e77da91 100644
--- a/src/main/java/net/imagej/ui/swing/viewer/image/AbstractSwingImageDisplayViewer.java
+++ b/src/main/java/net/imagej/ui/swing/viewer/image/AbstractSwingImageDisplayViewer.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/viewer/image/DatasetFigureView.java b/src/main/java/net/imagej/ui/swing/viewer/image/DatasetFigureView.java
index 2cf4c7e..d0eb523 100644
--- a/src/main/java/net/imagej/ui/swing/viewer/image/DatasetFigureView.java
+++ b/src/main/java/net/imagej/ui/swing/viewer/image/DatasetFigureView.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/viewer/image/FigureView.java b/src/main/java/net/imagej/ui/swing/viewer/image/FigureView.java
index 359929f..d6ce759 100644
--- a/src/main/java/net/imagej/ui/swing/viewer/image/FigureView.java
+++ b/src/main/java/net/imagej/ui/swing/viewer/image/FigureView.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/viewer/image/JHotDrawImageCanvas.java b/src/main/java/net/imagej/ui/swing/viewer/image/JHotDrawImageCanvas.java
index 73be363..f929709 100644
--- a/src/main/java/net/imagej/ui/swing/viewer/image/JHotDrawImageCanvas.java
+++ b/src/main/java/net/imagej/ui/swing/viewer/image/JHotDrawImageCanvas.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/viewer/image/OverlayFigureView.java b/src/main/java/net/imagej/ui/swing/viewer/image/OverlayFigureView.java
index 7acfe1b..9e3f54c 100644
--- a/src/main/java/net/imagej/ui/swing/viewer/image/OverlayFigureView.java
+++ b/src/main/java/net/imagej/ui/swing/viewer/image/OverlayFigureView.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayPanel.java b/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayPanel.java
index 6053cb1..96932e5 100644
--- a/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayPanel.java
+++ b/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayPanel.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayViewer.java b/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayViewer.java
index 93927c5..73a1ffc 100644
--- a/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayViewer.java
+++ b/src/main/java/net/imagej/ui/swing/viewer/image/SwingImageDisplayViewer.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/widget/DimSelectionWidget.java b/src/main/java/net/imagej/ui/swing/widget/DimSelectionWidget.java
index 442e2d2..e4f44eb 100644
--- a/src/main/java/net/imagej/ui/swing/widget/DimSelectionWidget.java
+++ b/src/main/java/net/imagej/ui/swing/widget/DimSelectionWidget.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/widget/SwingColorTableWidget.java b/src/main/java/net/imagej/ui/swing/widget/SwingColorTableWidget.java
index 1e96be4..f232f49 100644
--- a/src/main/java/net/imagej/ui/swing/widget/SwingColorTableWidget.java
+++ b/src/main/java/net/imagej/ui/swing/widget/SwingColorTableWidget.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/widget/SwingDimSelectionWidget.java b/src/main/java/net/imagej/ui/swing/widget/SwingDimSelectionWidget.java
index d0050bb..374623a 100644
--- a/src/main/java/net/imagej/ui/swing/widget/SwingDimSelectionWidget.java
+++ b/src/main/java/net/imagej/ui/swing/widget/SwingDimSelectionWidget.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/main/java/net/imagej/ui/swing/widget/SwingHistogramWidget.java b/src/main/java/net/imagej/ui/swing/widget/SwingHistogramWidget.java
index 95b0c0b..35a3a9e 100644
--- a/src/main/java/net/imagej/ui/swing/widget/SwingHistogramWidget.java
+++ b/src/main/java/net/imagej/ui/swing/widget/SwingHistogramWidget.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogDemo.java b/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogDemo.java
index 1e30083..eb9a2a8 100644
--- a/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogDemo.java
+++ b/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogDemo.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogTest.java b/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogTest.java
index 42fe1b8..3d3b49d 100644
--- a/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogTest.java
+++ b/src/test/java/net/imagej/ui/swing/updater/ReviewSiteURLsDialogTest.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
diff --git a/src/test/java/net/imagej/ui/swing/updater/UpdaterGUITest.java b/src/test/java/net/imagej/ui/swing/updater/UpdaterGUITest.java
index 3e79096..737c77d 100644
--- a/src/test/java/net/imagej/ui/swing/updater/UpdaterGUITest.java
+++ b/src/test/java/net/imagej/ui/swing/updater/UpdaterGUITest.java
@@ -2,7 +2,7 @@
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
- * Copyright (C) 2009 - 2023 ImageJ developers.
+ * Copyright (C) 2009 - 2024 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: