diff --git a/pom.xml b/pom.xml
index 16e45d68f..8a80f3706 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
sc.fiji
Simple_Neurite_Tracer
- 3.1.5-SNAPSHOT
+ 3.1.5
Simple Neurite Tracer
The ImageJ framework for semi-automated tracing of neurons and other tube-like structures.
diff --git a/src/main/java/tracing/NeuriteTracerResultsDialog.java b/src/main/java/tracing/NeuriteTracerResultsDialog.java
index 760323332..5975bc37a 100644
--- a/src/main/java/tracing/NeuriteTracerResultsDialog.java
+++ b/src/main/java/tracing/NeuriteTracerResultsDialog.java
@@ -38,6 +38,7 @@
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.TextField;
import java.awt.event.ActionEvent;
@@ -101,8 +102,9 @@ public class NeuriteTracerResultsDialog extends JDialog implements ActionListene
public static final boolean verbose = SimpleNeuriteTracer.verbose;
- public PathWindow pw;
- public FillWindow fw;
+ private PathWindow pw;
+ private FillWindow fw;
+ private SNTPrefs prefs;
protected JMenuBar menuBar;
protected JMenu fileMenu;
@@ -478,7 +480,7 @@ protected void exitRequested() {
plugin.cancelSearch(true);
plugin.notifyListeners(new SNTEvent(SNTEvent.QUIT));
- new SNTPrefs(plugin).savePluginPrefs();
+ prefs.savePluginPrefs();
pw.dispose();
fw.dispose();
dispose();
@@ -762,6 +764,7 @@ public NeuriteTracerResultsDialog(final String title, final SimpleNeuriteTracer
new ClarifyingKeyListener().addKeyAndContainerListenerRecursively(this);
this.plugin = plugin;
+ prefs = plugin.prefs;
final SimpleNeuriteTracer thisPlugin = plugin;
this.launchedByArchive = launchedByArchive;
@@ -1175,7 +1178,8 @@ protected void displayOnStarting() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- arrangeDialogs();
+ if (plugin.prefs.isSaveWinLocations())
+ arrangeDialogs();
arrangeCanvases();
setVisible(true);
setPathListVisible(true, false);
@@ -1600,14 +1604,20 @@ else if (reset)
}
private void arrangeDialogs() {
- final GraphicsDevice activeScreen = getGraphicsConfiguration().getDevice();
- final int screenWidth = activeScreen.getDisplayMode().getWidth();
- final int screenHeight = activeScreen.getDisplayMode().getHeight();
- final Rectangle bounds = activeScreen.getDefaultConfiguration().getBounds();
-
- setLocation(bounds.x, bounds.y);
- pw.setLocation(screenWidth - pw.getWidth(), bounds.y);
- fw.setLocation(bounds.x + getWidth(), screenHeight - fw.getHeight());
+ Point loc = prefs.getPathWindowLocation();
+ if (loc != null)
+ pw.setLocation(loc);
+ loc = prefs.getFillWindowLocation();
+ if (loc != null)
+ fw.setLocation(loc);
+// final GraphicsDevice activeScreen = getGraphicsConfiguration().getDevice();
+// final int screenWidth = activeScreen.getDisplayMode().getWidth();
+// final int screenHeight = activeScreen.getDisplayMode().getHeight();
+// final Rectangle bounds = activeScreen.getDefaultConfiguration().getBounds();
+//
+// setLocation(bounds.x, bounds.y);
+// pw.setLocation(screenWidth - pw.getWidth(), bounds.y);
+// fw.setLocation(bounds.x + getWidth(), screenHeight - fw.getHeight());
}
private void arrangeCanvases() {
@@ -1885,7 +1895,7 @@ private JMenu tracingMenu() {
optionsMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
- new SNTPrefs(plugin).promptForOptions();
+ prefs.promptForOptions();
}
});
tracingMenu.add(optionsMenuItem);
@@ -1976,4 +1986,12 @@ public void actionPerformed(final ActionEvent e) {
return mi;
}
+ public PathWindow getPathWindow() {
+ return pw;
+ }
+
+ public FillWindow getFillWindow() {
+ return fw;
+ }
+
}
diff --git a/src/main/java/tracing/PathAndFillManager.java b/src/main/java/tracing/PathAndFillManager.java
index 26d8a63fe..862b91c20 100644
--- a/src/main/java/tracing/PathAndFillManager.java
+++ b/src/main/java/tracing/PathAndFillManager.java
@@ -2024,7 +2024,17 @@ synchronized void setPathPointsInVolume(final ArrayList paths, final byte[
*/
final List pointsToDraw = Bresenham3D.bresenham3D(previous, current);
for (final Bresenham3D.IntegerPoint ip : pointsToDraw) {
- slices[ip.z][ip.y * width + ip.x] = (byte) 255;
+ try {
+ slices[ip.z][ip.y * width + ip.x] = (byte) 255;
+ } catch (final ArrayIndexOutOfBoundsException ignored) {
+ final int x = Math.min(width - 1, Math.max(0, ip.x));
+ final int y = Math.min(height - 1, Math.max(0, ip.y));
+ final int z = Math.min(depth - 1, Math.max(0, ip.z));
+ slices[z][y * width + x] = (byte) 255;
+ if (SimpleNeuriteTracer.verbose)
+ SNT.log(String.format("Bresenham3D: Forced out-of-bounds point to [%d][%d * %d + %d]",
+ z, y, width, x));
+ }
}
}
diff --git a/src/main/java/tracing/SNTPrefs.java b/src/main/java/tracing/SNTPrefs.java
index ffe850b1f..a68411e54 100644
--- a/src/main/java/tracing/SNTPrefs.java
+++ b/src/main/java/tracing/SNTPrefs.java
@@ -1,6 +1,7 @@
package tracing;
import java.awt.Font;
+import java.awt.Point;
import ij.Prefs;
import ij.gui.GenericDialog;
@@ -22,6 +23,7 @@ public class SNTPrefs {
private static final int LOOK_FOR_TUBES = 128;
private static final int LOOK_FOR_OOF = 256;
private static final int SHOW_ONLY_SELECTED = 512;
+ private static final int STORE_WIN_LOCATIONS = 1024;
// private static final int JUST_NEAR_SLICES = 1024;
private static final int ENFORCE_DEFAULT_PATH_COLORS = 2048;
private static final int DEBUG = 4096;
@@ -31,6 +33,11 @@ public class SNTPrefs {
private static final String BOOLEANS = "tracing.snt.booleans";
private static final String SNAP_XY = "tracing.snt.xysnap";
private static final String SNAP_Z = "tracing.snt.zsnap";
+ private static final String PATHWIN_LOC = "tracing.snt.pwloc";
+ private static final String FILLWIN_LOC = "tracing.snt.fwloc";
+
+ //private static final String SNAP_Z = "tracing.snt.zsnap";
+
// private final static String NEARBY_VIEW = "tracing.snt.nearbyview";
private final int UNSET_PREFS = -1;
@@ -60,6 +67,7 @@ private void getBooleans() {
}
protected void loadPluginPrefs() {
+ getBooleans();
snt.useCompressedXML = getPref(COMPRESSED_XML);
snt.autoCanvasActivation = getPref(AUTO_CANVAS_ACTIVATION);
snt.snapCursor = getPref(SNAP_CURSOR);
@@ -121,6 +129,21 @@ protected void savePluginPrefs() {
setPref(DEBUG, SimpleNeuriteTracer.verbose);
Prefs.set(BOOLEANS, currentBooleans);
clearLegacyPrefs();
+ if (isSaveWinLocations()) {
+ final NeuriteTracerResultsDialog rd = snt.resultsDialog;
+ if (rd == null)
+ return;
+ final PathWindow pw = rd.getPathWindow();
+ if (pw != null)
+ Prefs.saveLocation(PATHWIN_LOC, pw.getLocation());
+ final FillWindow fw = rd.getFillWindow();
+ if (fw != null)
+ Prefs.saveLocation(FILLWIN_LOC, fw.getLocation());
+ }
+ }
+
+ protected boolean isSaveWinLocations() {
+ return getPref(STORE_WIN_LOCATIONS);
}
private void setPref(final int key, final boolean value) {
@@ -130,11 +153,21 @@ private void setPref(final int key, final boolean value) {
currentBooleans &= ~key;
}
+ protected Point getPathWindowLocation() {
+ return Prefs.getLocation(PATHWIN_LOC);
+ }
+
+ protected Point getFillWindowLocation() {
+ return Prefs.getLocation(FILLWIN_LOC);
+ }
+
private void resetOptions() {
clearLegacyPrefs();
Prefs.set(BOOLEANS, null);
Prefs.set(SNAP_XY, null);
Prefs.set(SNAP_Z, null);
+ Prefs.set(FILLWIN_LOC, null);
+ Prefs.set(PATHWIN_LOC, null);
currentBooleans = UNSET_PREFS;
}
@@ -144,7 +177,7 @@ private void clearLegacyPrefs() {
protected void promptForOptions() {
- final int startupOptions = 6;
+ final int startupOptions = 7;
final int pluginOptions = 2;
final String[] startupLabels = new String[startupOptions];
@@ -176,6 +209,10 @@ protected void promptForOptions() {
startupLabels[idx] = "Load_default \".traces\" file (if present)";
startupStates[idx++] = snt.look4tracesFile;
+ startupItems[idx] = STORE_WIN_LOCATIONS;
+ startupLabels[idx] = "Remember window locations across restarts";
+ startupStates[idx++] = isSaveWinLocations();
+
final String[] pluginLabels = new String[pluginOptions];
final int[] pluginItems = new int[pluginOptions];
final boolean[] pluginStates = new boolean[pluginOptions];
diff --git a/src/main/java/tracing/ShollAnalysisPlugin.java b/src/main/java/tracing/ShollAnalysisPlugin.java
index 00c9bad5c..7d97080f1 100644
--- a/src/main/java/tracing/ShollAnalysisPlugin.java
+++ b/src/main/java/tracing/ShollAnalysisPlugin.java
@@ -285,7 +285,7 @@ private boolean showDialog() {
if (gd.wasCanceled())
return false;
else if (gd.wasOKed()) {
- sholl.gui.Utils.improveRecording();
+ Utils.improveRecording();
return dialogItemChanged(gd, null);
}
return false;
@@ -317,7 +317,7 @@ public void run() {
popup.addSeparator();
mi = Utils.menuItemTrigerringURL("Online Documentation", Sholl_Analysis.URL + "#Traces");
popup.add(mi);
- mi = sholl.gui.Utils.menuItemTriggeringResources();
+ mi = Utils.menuItemTriggeringResources();
popup.add(mi);
return popup;
}
@@ -356,15 +356,15 @@ public boolean dialogItemChanged(final GenericDialog arg0, final AWTEvent event)
for (int i = 2; i < cbxs.size(); i++)
((Checkbox) cbxs.get(i)).setEnabled(restrictBySWCType);
- boolean enableOK = true;
+ //boolean enableOK = true;
String warning = "";
if (impRequired && !validImageFile(new File(imgPath))) {
- enableOK = false;
+ //enableOK = false;
warning += "Not a valid image. ";
}
if (!validTracesFile(new File(tracesPath))) {
- enableOK = false;
+ //enableOK = false;
warning += "Not a valid .traces/.(e)swc file";
}
if (!warning.isEmpty()) {
@@ -375,7 +375,7 @@ public boolean dialogItemChanged(final GenericDialog arg0, final AWTEvent event)
infoMsg.setText(defaultInfoMsg);
}
- return enableOK;
+ return true; //enableOK
}
private String getFilePathWithoutExtension(final String filePath) {
@@ -451,10 +451,8 @@ private boolean validTracesFile(final File file) {
* We'll need to remove those to avoid I/O errors.
*/
private String normalizedPath(final String path) {
- // This is way to simplistic: See
// chase-seibert.github.io/blog/2009/04/10/java-replaceall-fileseparator.html
- return path.replaceAll(Matcher.quoteReplacement(File.separator) + "+",
- Matcher.quoteReplacement(File.separator));
+ return path.replaceAll("(? fromPaths) {
// currentlyFilling = true;
- resultsDialog.fw.pauseOrRestartFilling.setText("Pause");
+ resultsDialog.getFillWindow().pauseOrRestartFilling.setText("Pause");
filler = new FillerThread(xy, stackMin, stackMax, false, // startPaused
true, // reciprocal
@@ -1246,7 +1247,7 @@ synchronized public void startFillingPaths(final Set fromPaths) {
addThreadToDraw(filler);
filler.addProgressListener(this);
- filler.addProgressListener(resultsDialog.fw);
+ filler.addProgressListener(resultsDialog.getFillWindow());
filler.setSourcePaths(fromPaths);
@@ -1565,14 +1566,14 @@ public void selectPath(final Path p, final boolean addToExistingSelection) {
else
pathsToSelect.add(p);
if (addToExistingSelection) {
- pathsToSelect.addAll(resultsDialog.pw.getSelectedPaths());
+ pathsToSelect.addAll(resultsDialog.getPathWindow().getSelectedPaths());
}
- resultsDialog.pw.setSelectedPaths(pathsToSelect, this);
+ resultsDialog.getPathWindow().setSelectedPaths(pathsToSelect, this);
}
public Set getSelectedPaths() {
- if (resultsDialog.pw != null) {
- return resultsDialog.pw.getSelectedPaths();
+ if (resultsDialog.getPathWindow() != null) {
+ return resultsDialog.getPathWindow().getSelectedPaths();
}
throw new RuntimeException("getSelectedPaths was called when resultsDialog.pw was null");
}
diff --git a/src/main/java/tracing/Simple_Neurite_Tracer.java b/src/main/java/tracing/Simple_Neurite_Tracer.java
index d32b5bc80..6e14f10aa 100644
--- a/src/main/java/tracing/Simple_Neurite_Tracer.java
+++ b/src/main/java/tracing/Simple_Neurite_Tracer.java
@@ -184,7 +184,7 @@ public void run(final String ignoredArguments) {
spacing_units = "" + calibration.getUnit();
}
- final SNTPrefs prefs = new SNTPrefs(this);
+ prefs = new SNTPrefs(this);
prefs.loadStartupPrefs();
final GenericDialog gd = new GenericDialog("Simple Neurite Tracer (v" + SNT.VERSION + ")");