Skip to content

Commit

Permalink
Minor UI improvements
Browse files Browse the repository at this point in the history
- MeasureUI:
  - Allow prompt to "reload"
  - Ensure MeasureUI preferences are set before exit
  - Clarify when measurements are being split into compartments
- Allow ColorMapper to proceed if NaN is unset
- Adjust Viewer_3D message as it works way better than expected
- Minor cleanup
  • Loading branch information
tferr committed Oct 16, 2024
1 parent 1d4badb commit 405cb97
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 96 deletions.
15 changes: 11 additions & 4 deletions src/main/java/sc/fiji/snt/PathManagerUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -2258,10 +2258,17 @@ protected void saveTable() {
protected void measureCells() {
final Collection<Tree> trees = getMultipleTrees();
if (trees == null) return;
if (!MeasureUI.instances.isEmpty()) {
guiUtils.error("A Measurements prompt seems to be already open.");
MeasureUI.instances.get(MeasureUI.instances.size()-1).toFront();
} else {
boolean newInstance = true;
if (MeasureUI.instances != null && !MeasureUI.instances.isEmpty()) {
if (guiUtils.getConfirmation("A Measurements prompt seems to be already open. Close it?",
"Measurements Prompt Already Open")) {
MeasureUI.instances.get(MeasureUI.instances.size() - 1).dispose();
} else {
newInstance = false;
MeasureUI.instances.get(MeasureUI.instances.size()-1).toFront();
}
}
if (newInstance) {
new MeasureUI(plugin, trees).setVisible(true);
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/sc/fiji/snt/SNTUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,8 @@ public void windowClosing(final WindowEvent e) {
InternalUtils.addSeparatorWithURL(tab3, "Legacy 3D Viewer:", true, c3);
++c3.gridy;
final String msg2 =
"The Legacy 3D Viewer is a functional tracing canvas " +
"but it depends on outdated services that are now deprecated. " +
"It may not function reliably on recent operating systems.";
"The Legacy 3D Viewer is a functional tracing canvas but it depends on " +
"stalled services that may not function reliably during complex tasks.";
tab3.add(largeMsg(msg2), c3);
c3.gridy++;
try {
Expand Down
45 changes: 32 additions & 13 deletions src/main/java/sc/fiji/snt/gui/MeasureUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class MeasureUI extends JFrame {
private static final Class<?>[] columnClasses = new Class<?>[] { String.class, Boolean.class, Boolean.class,
Boolean.class, Boolean.class, Boolean.class, Boolean.class };
public static final List<MeasureUI> instances = new ArrayList<>();
private final MeasurePanel panel;

@Parameter
private PrefService prefService;
Expand Down Expand Up @@ -100,7 +101,7 @@ private MeasureUI(final Context context, final Collection<Tree> trees) {
super("SNT Measurements");
context.inject(this);
guiUtils = new GuiUtils(this);
final MeasurePanel panel = new MeasurePanel(trees);
panel = new MeasurePanel(trees);
add(panel);
pack();
instances.add(this);
Expand All @@ -110,19 +111,22 @@ private MeasureUI(final Context context, final Collection<Tree> trees) {
public void windowClosing(final WindowEvent e) {
final boolean exit = backgroundTask == null || backgroundTask.isDone() || guiUtils.getConfirmation(
"Measurements are still being retrieved. Interrupt nevertheless?", "Interrupt?");
if (exit) {
panel.savePreferences();
instances.remove(MeasureUI.this);
if (backgroundTask != null && !backgroundTask.isDone()) {
backgroundTask.cancel(true);
backgroundTask.done();
}
dispose();
}
if (exit) dispose();
}
});
}

@Override
public void dispose() {
panel.savePreferences();
instances.remove(MeasureUI.this);
if (backgroundTask != null && !backgroundTask.isDone()) {
backgroundTask.cancel(true);
backgroundTask.done();
}
super.dispose();
}

@Override
public void setVisible(final boolean b) {
// Script friendly version
Expand Down Expand Up @@ -173,6 +177,7 @@ class MeasurePanel extends JPanel {
private static final long serialVersionUID = 1L;
private final CheckBoxList metricList;
private final DefaultTableModel statsTableModel;
private final JButton runButton;

@SuppressWarnings("unchecked")
MeasurePanel(final Collection<Tree> trees) {
Expand Down Expand Up @@ -285,7 +290,8 @@ public void componentResized(final ComponentEvent e) {
TablePopupMenu.install(statsTable, statsTableScrollPane);
add(statsTableScrollPane, c);

final JButton runButton = new JButton("Measure " + trees.size() + " Reconstruction(s)");
runButton = new JButton("Measure 100 Comp. Reconstruction(s)");
updateRunButtonLabel(trees.size());
runButton.addActionListener(new GenerateTableAction(trees, statsTableModel));
final JButton optionsButton = optionsButton(trees);
GuiUtils.equalizeHeight(runButton, optionsButton);
Expand All @@ -304,15 +310,28 @@ public void componentResized(final ComponentEvent e) {
add(buttonPanel, c);
}

private void updateRunButtonLabel(final int nTrees) {
SwingUtilities.invokeLater(() -> {
runButton.setText(
String.format("Measure %d %s Reconstruction(s)", nTrees, (distinguishCompartments) ? "Comp. " : ""));
runButton.setToolTipText((distinguishCompartments)
? "Measurements will be split into known compartments\n(axon, dendrites, etc.)"
: "Measurements will be retrieved for the whole cell\nwithout compartment (axon, dendrites, etc.) distinction");
});
}

private JButton optionsButton(final Collection<Tree> trees) {
final JButton optionsButton = new JButton(IconFactory.getButtonIcon(IconFactory.GLYPH.OPTIONS, 1.3f));
optionsButton.setToolTipText("Options & Utilities");
final JPopupMenu optionsMenu = new JPopupMenu();
GuiUtils.addSeparator(optionsMenu, "Options:");
final JCheckBoxMenuItem jcmi1 = new JCheckBoxMenuItem("Distinguish Compartments",
distinguishCompartments);
jcmi1.addActionListener(e -> distinguishCompartments = jcmi1.isSelected());
jcmi1.setToolTipText("Whether measurements should be grouped by cellular\n"
jcmi1.addActionListener(e -> {
distinguishCompartments = jcmi1.isSelected();
updateRunButtonLabel(trees.size());
});
jcmi1.setToolTipText("Whether measurements should be slip into cellular\n"
+ "compartment (e.g., \"axon\", \"dendrites\", etc.)");
optionsMenu.add(jcmi1);
final JCheckBoxMenuItem jcmi4 = new JCheckBoxMenuItem("Debug mode", SNTUtils.isDebugMode());
Expand Down
72 changes: 8 additions & 64 deletions src/main/java/sc/fiji/snt/gui/SNTCommandFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,7 @@

package sc.fiji.snt.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
Expand All @@ -49,35 +42,13 @@
import java.util.Map;
import java.util.TreeMap;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.MenuElement;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;

import org.scijava.ui.awt.AWTWindows;
import org.scijava.util.PlatformUtils;

import com.formdev.flatlaf.FlatClientProperties;
Expand Down Expand Up @@ -136,21 +107,6 @@ public SNTCommandFinder(final Viewer3D viewer3D) {
guiUtils = new GuiUtils(viewer3D.getFrame());
}

void install(final JMenu toolsMenu) {
final Action action = new AbstractAction(NAME) {

private static final long serialVersionUID = -7030359886427866104L;

@Override
public void actionPerformed(final ActionEvent e) {
toggleVisibility();
}

};
action.putValue(Action.ACCELERATOR_KEY, ACCELERATOR);
toolsMenu.add(new JMenuItem(action));
}

Map<String, String> getShortcuts() {
if (!cmdScrapper.scrapeSuccessful())
cmdScrapper.scrape();
Expand Down Expand Up @@ -530,12 +486,6 @@ JToggleButton recordButton( ) {
});
return recButton;
}

@Override
Font getPlaceholderFont() {
return getFont().deriveFont(Font.ITALIC);
}

}

private class PromptDocumentListener implements DocumentListener {
Expand Down Expand Up @@ -658,17 +608,11 @@ void center() {
}

void center(final Container component) {
if (component == null)
return;
final Rectangle bounds = component.getBounds();
final Dimension w = getSize();
int x = bounds.x + (bounds.width - w.width) / 2;
int y = bounds.y + (bounds.height - w.height) / 2;
if (x < 0)
x = 0; //component.getX();
if (y < 0)
y = 0;// component.getY();
setLocation(x, y);
if (component == null) {
AWTWindows.centerWindow(this);
} else {
AWTWindows.centerWindow(component.getBounds(), this);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/sc/fiji/snt/gui/cmds/FigCreatorCmd.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,16 @@ private void init() {
final ArrayList<String> choices = new ArrayList<>(mi.getChoices());
choices.remove(0);
mi.setChoices(choices);
} else {
resolveInput("noRasterOutput");
}
if (noGeodesicTransformation) {
final MutableModuleItem<String> mi = (MutableModuleItem<String>) getInfo().getInput("uprightRotation", String.class);
final ArrayList<String> choices = new ArrayList<>(mi.getChoices());
choices.remove(1);
mi.setChoices(choices);
} else {
resolveInput("noGeodesicTransformation");
}
}

Expand Down
21 changes: 14 additions & 7 deletions src/main/java/sc/fiji/snt/plugin/TreeMapperCmd.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.scijava.plugin.Plugin;
import org.scijava.prefs.PrefService;
import org.scijava.util.ColorRGB;
import org.scijava.util.Colors;
import org.scijava.widget.Button;

import sc.fiji.snt.analysis.*;
Expand Down Expand Up @@ -102,6 +103,10 @@ public class TreeMapperCmd extends CommonDynamicCmd {
@Override
public void run() {

if (nanColor == null) {
error("Color for \"undefined values\" has not been specified. Please define it and re-run.");
return;
}
statusService.showStatus("Applying Color Code...");
SNTUtils.log("Color Coding Tree (" + measurementChoice + ") using " + lutChoice);

Expand All @@ -120,15 +125,15 @@ public void run() {
try {
if (trees.size() == 1) {
mapper = new TreeColorMapper(context());
mapper.setMinMax(Double.NaN, Double.NaN);
if (nanColor != null)
mapper.setNaNColor(new Color(nanColor.getRed(), nanColor.getGreen(), nanColor.getBlue()));
mapper.map(trees.iterator().next(), measurementChoice, colorTable);
} else {
mapper = new MultiTreeColorMapper(trees);
mapper.setMinMax(Double.NaN, Double.NaN);
if (nanColor != null)
mapper.setNaNColor(new Color(nanColor.getRed(), nanColor.getGreen(), nanColor.getBlue()));
}
mapper.setMinMax(Double.NaN, Double.NaN);
if (nanColor != null)
mapper.setNaNColor(new Color(nanColor.getRed(), nanColor.getGreen(), nanColor.getBlue()));
if (trees.size() == 1) {
mapper.map(trees.iterator().next(), measurementChoice, colorTable);
} else {
mapper.map(measurementChoice, colorTable);
}
} catch (final IllegalArgumentException exc) {
Expand Down Expand Up @@ -157,6 +162,8 @@ private void init() {
resolveInput("onlyConnectivitySafeMetrics");
if (lutChoice == null) lutChoice = prefService.get(getClass(), "lutChoice",
"mpl-viridis.lut");
if (nanColor == null)
nanColor = Colors.GRAY;
setChoices();
setLUTs();
}
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/sc/fiji/snt/viewer/Viewer3D.java
Original file line number Diff line number Diff line change
Expand Up @@ -4560,13 +4560,20 @@ private JPopupMenu measureMenu() {
mi.addActionListener(e -> {
List<Tree> trees = getSelectedTrees();
if (trees == null || trees.isEmpty()) return;
initTable();
boolean newInstance = true;
if (MeasureUI.instances != null && !MeasureUI.instances.isEmpty()) {
guiUtils.error("A Measurements prompt seems to be already open.");
MeasureUI.instances.get(MeasureUI.instances.size()-1).toFront();
trees = null;
} else {
if (guiUtils.getConfirmation("A Measurements prompt seems to be already open. Close it?",
"Measurements Prompt Already Open")) {
MeasureUI.instances.get(MeasureUI.instances.size() - 1).dispose();
} else {
newInstance = false;
MeasureUI.instances.get(MeasureUI.instances.size()-1).toFront();
trees = null;
}
}
if (newInstance) {
final MeasureUI measureUI = new MeasureUI(trees);
initTable();
measureUI.setTable(table);
measureUI.setVisible(true);
}
Expand Down

0 comments on commit 405cb97

Please sign in to comment.