diff --git a/src/main/java/ai/nets/samj/gui/MainGUI.java b/src/main/java/ai/nets/samj/gui/MainGUI.java index 4043f24..c72eb9f 100644 --- a/src/main/java/ai/nets/samj/gui/MainGUI.java +++ b/src/main/java/ai/nets/samj/gui/MainGUI.java @@ -13,6 +13,7 @@ import ai.nets.samj.gui.components.ModelDrawerPanel.ModelDrawerPanelListener; import ai.nets.samj.models.AbstractSamJ.BatchCallback; import ai.nets.samj.ui.ConsumerInterface; +import ai.nets.samj.ui.ConsumerInterface.ConsumerCallback; import ai.nets.samj.utils.Constants; import net.imglib2.RandomAccessibleInterval; import net.imglib2.type.NativeType; @@ -40,7 +41,10 @@ public class MainGUI extends JFrame { private ModelSelectionListener modelListener; private ModelDrawerPanelListener modelDrawerListener; private BatchCallback batchDrawerCallback; + private ConsumerCallback consumerCallback; + private ConsumerInterface consumer; + private boolean isValidPrompt = true; private JCheckBox chkRoiManager = new JCheckBox("Add to RoiManager", true); private JCheckBox retunLargest = new JCheckBox("Only return largest ROI", true); @@ -58,6 +62,7 @@ public class MainGUI extends JFrame { private final ImageSelection cmbImages; private ModelDrawerPanel drawerPanel; private JPanel cardPanel; + private JPanel cardPanel1_2; private static double HEADER_VERTICAL_RATIO = 0.1; @@ -68,6 +73,8 @@ public class MainGUI extends JFrame { private static String MANUAL_STR = "Manual"; private static String PRESET_STR = "Preset prompts"; private static String ROIM_STR = "Selection from ROIManager"; + private static String VISIBLE_STR = "visible"; + private static String INVISIBLE_STR = "invisible"; private static final List DEFAULT_MODEL_LIST = new ArrayList<>(); static { @@ -87,6 +94,8 @@ public MainGUI(List modelList, ConsumerInterface consumer) { createListeners(); this.consumer = consumer; + this.consumer.setCallback(consumerCallback); + consumerCallback.validPromptChosen(consumer.isValidPromptSelected()); cmbImages = ImageSelection.create(this.consumer, imageListener); if (modelList == null) this.modelList = DEFAULT_MODEL_LIST; @@ -101,7 +110,7 @@ public MainGUI(List modelList, ConsumerInterface consumer) { cmbModels.getButton().addActionListener(e -> toggleDrawer()); go.addActionListener(e -> loadModel()); export.addActionListener(e -> consumer.exportImageLabeling()); - chkInstant.addActionListener(e -> setInstantPromptsEnabled(this.chkInstant.isSelected())); + chkInstant.addActionListener(e -> setInstantPromptsEnabled(this.chkInstant.isSelected() && this.isValidPrompt)); chkRoiManager.addActionListener(e -> consumer.enableAddingToRoiManager(chkRoiManager.isSelected())); retunLargest.addActionListener(e -> cmbModels.getSelectedModel().setReturnOnlyBiggest(retunLargest.isSelected())); btnBatchSAMize.addActionListener(e -> batchSAMize()); @@ -198,7 +207,7 @@ private void loadModel() { consumer.enableAddingToRoiManager(this.chkRoiManager.isSelected()); consumer.setFocusedImage(cmbImages.getSelectedObject()); consumer.setModel(cmbModels.getSelectedModel()); - setInstantPromptsEnabled(this.chkInstant.isSelected()); + setInstantPromptsEnabled(this.chkInstant.isSelected() && this.isValidPrompt); cmbModels.getSelectedModel().setReturnOnlyBiggest(retunLargest.isSelected()); setTwoThirdsEnabled(true); } catch (IOException | RuntimeException | InterruptedException ex) { @@ -337,13 +346,16 @@ private JPanel createSecondComponent() { gbc0.gridy = 0; gbc0.weighty = 0.2; gbc0.anchor = GridBagConstraints.NORTH; - card1.add(new JLabel("Instant Annotation"), gbc0); + cardPanel1_2 = new JPanel(new CardLayout()); + cardPanel1_2.add(new JPanel() {{ setOpaque(false); }}, INVISIBLE_STR); + cardPanel1_2.add(new JLabel("⚠ Only rect and points!"), VISIBLE_STR); + card1.add(cardPanel1_2, gbc0); gbc0.gridy = 1; gbc0.anchor = GridBagConstraints.CENTER; gbc0.fill = GridBagConstraints.BOTH; gbc0.weighty = 0.8; - gbc0.insets = new Insets(0, 0, 10, 0); + gbc0.insets = new Insets(0, 5, 10, 5); card1.add(chkInstant, gbc0); JPanel card2 = new JPanel(new GridBagLayout()); @@ -387,6 +399,7 @@ private JPanel createSecondComponent() { radioButton1.addActionListener(e -> { CardLayout cl = (CardLayout) (cardPanel.getLayout()); cl.show(cardPanel, MANUAL_STR); + this.chkInstant.setEnabled(this.isValidPrompt); }); radioButton2.addActionListener(e -> { @@ -570,6 +583,27 @@ public void deleteRectPrompt(List promptList) { } }; + + consumerCallback = new ConsumerCallback() { + + @Override + public void validPromptChosen(boolean isValid) { + if (isValid && !isValidPrompt) { + CardLayout lyt = (CardLayout) cardPanel1_2.getLayout(); + lyt.show(cardPanel1_2, INVISIBLE_STR); + isValidPrompt = true; + MainGUI.this.chkInstant.setEnabled(true); + } else if (!isValid && isValidPrompt) { + CardLayout lyt = (CardLayout) cardPanel1_2.getLayout(); + lyt.show(cardPanel1_2, VISIBLE_STR); + isValidPrompt = false; + MainGUI.this.chkInstant.setSelected(false); + MainGUI.this.chkInstant.setEnabled(false); + MainGUI.this.setInstantPromptsEnabled(false);; + } + } + + }; } public static void main(String[] args) { diff --git a/src/main/java/ai/nets/samj/models/AbstractSamJ.java b/src/main/java/ai/nets/samj/models/AbstractSamJ.java index d4f4bd5..166002f 100644 --- a/src/main/java/ai/nets/samj/models/AbstractSamJ.java +++ b/src/main/java/ai/nets/samj/models/AbstractSamJ.java @@ -78,7 +78,6 @@ public abstract class AbstractSamJ implements AutoCloseable { protected static String UPDATE_ID_CONTOUR = "FOUND_CONTOUR_" + UUID.randomUUID().toString(); - /** Essentially, a syntactic-shortcut for a String consumer */ public interface BatchCallback { void setTotalNumberOfRois(int nRois); diff --git a/src/main/java/ai/nets/samj/ui/ConsumerInterface.java b/src/main/java/ai/nets/samj/ui/ConsumerInterface.java index c502fbb..127b197 100644 --- a/src/main/java/ai/nets/samj/ui/ConsumerInterface.java +++ b/src/main/java/ai/nets/samj/ui/ConsumerInterface.java @@ -38,6 +38,14 @@ public abstract class ConsumerInterface { protected SAMModel selectedModel; + + public interface ConsumerCallback { + + void validPromptChosen(boolean isValid); + + } + + protected ConsumerCallback callback; /** * Method to be implemented in the softwar that wants to use the SAMJ default GUI. @@ -91,8 +99,14 @@ public abstract class ConsumerInterface { public abstract void deletePointRoi(int[] pp); public abstract void deleteRectRoi(Rectangle rect); + + public abstract boolean isValidPromptSelected(); public void setModel(SAMModel model) { this.selectedModel = model; } + + public void setCallback(ConsumerCallback callback) { + this.callback = callback; + } }