diff --git a/src/main/java/ai/nets/samj/gui/HTMLPane2.java b/src/main/java/ai/nets/samj/gui/HTMLPane2.java
deleted file mode 100644
index 0006365..0000000
--- a/src/main/java/ai/nets/samj/gui/HTMLPane2.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package ai.nets.samj.gui;
-
-import java.awt.Dimension;
-
-import javax.swing.JEditorPane;
-import javax.swing.JScrollPane;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-
-/**
- * This class extends the Java JEditorPane to make a easy to use panel to
- * display HTML information.
- *
- * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland.
- *
- */
-public class HTMLPane2 extends JEditorPane {
-
- private String html = "";
- private String header = "";
- private String footer = "";
- private Dimension dim;
- private String font = "verdana";
- private String color = "#222222";
- private String background = "#f8f8f8";
-
- public HTMLPane2() {
- create();
- }
-
- public HTMLPane2(String font) {
- this.font = font;
- create();
- }
-
- public HTMLPane2(int width, int height) {
- this.dim = new Dimension(width, height);
- create();
- }
-
- public HTMLPane2(String font, int width, int height) {
- this.font = font;
- this.dim = new Dimension(width, height);
- create();
- }
-
- public HTMLPane2(String font, String color, String background, int width, int height) {
- this.font = font;
- this.dim = new Dimension(width, height);
- this.color = color;
- this.background = background;
- create();
- }
-
- @Override
- public String getText() {
- Document doc = this.getDocument();
- try {
- return doc.getText(0, doc.getLength());
- }
- catch (BadLocationException e) {
- e.printStackTrace();
- return getText();
- }
- }
-
- public void clear() {
- html = "";
- append("");
- }
-
- private void create() {
- header += "\n";
- header += "
\n";
- header += "\n";
- header += "\n";
- header += "\n";
- header += "\n";
- header += "\n";
- header += "\n";
- header += "\n";
- footer += "\n";
- setEditable(false);
- setContentType("text/html; charset=ISO-8859-1");
- }
-
- public void append(String content) {
- html += content;
- setText(header + html + footer);
- if (dim != null) {
- setPreferredSize(dim);
- }
- setCaretPosition(0);
- }
-
- public void append(String tag, String content) {
- html += "<" + tag + ">" + content + "" + tag + ">";
- setText(header + html + footer);
- if (dim != null) {
- setPreferredSize(dim);
- }
- setCaretPosition(0);
- }
-
- public JScrollPane getPane() {
- JScrollPane scroll = new JScrollPane(this, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- scroll.setPreferredSize(dim);
- return scroll;
- }
-}
diff --git a/src/main/java/ai/nets/samj/gui2/icons/LoadingButton.java b/src/main/java/ai/nets/samj/gui/LoadingButton.java
similarity index 99%
rename from src/main/java/ai/nets/samj/gui2/icons/LoadingButton.java
rename to src/main/java/ai/nets/samj/gui/LoadingButton.java
index c002910..6d881ab 100644
--- a/src/main/java/ai/nets/samj/gui2/icons/LoadingButton.java
+++ b/src/main/java/ai/nets/samj/gui/LoadingButton.java
@@ -17,7 +17,7 @@
* limitations under the License.
* #L%
*/
-package ai.nets.samj.gui.icons;
+package ai.nets.samj.gui;
import java.awt.Image;
import java.io.File;
diff --git a/src/main/java/ai/nets/samj/gui2/SAMJDialog.java b/src/main/java/ai/nets/samj/gui2/SAMJDialog.java
deleted file mode 100644
index 718b918..0000000
--- a/src/main/java/ai/nets/samj/gui2/SAMJDialog.java
+++ /dev/null
@@ -1,618 +0,0 @@
-/*-
- * #%L
- * Library to call models of the family of SAM (Segment Anything Model) from Java
- * %%
- * Copyright (C) 2024 SAMJ developers.
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-package ai.nets.samj.gui;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.awt.dnd.DnDConstants;
-import java.awt.dnd.DropTarget;
-import java.awt.dnd.DropTargetDropEvent;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.stream.IntStream;
-
-import javax.swing.BorderFactory;
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JFileChooser;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import javax.swing.JToolBar;
-import javax.swing.SwingUtilities;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-
-import ai.nets.samj.communication.model.SAMModel;
-import ai.nets.samj.communication.model.SAMModels;
-import ai.nets.samj.gui.components.ComboBoxItem;
-import ai.nets.samj.gui.components.GridPanel;
-import ai.nets.samj.gui.icons.ButtonIcon;
-import ai.nets.samj.gui.icons.LoadingButton;
-import ai.nets.samj.gui.tools.Tools;
-import ai.nets.samj.install.SamEnvManagerAbstract;
-import ai.nets.samj.ui.PromptsResultsDisplay;
-import ai.nets.samj.ui.PromptsResultsDisplay.SAMJException;
-import ai.nets.samj.ui.SAMJLogger;
-import ai.nets.samj.ui.UtilityMethods;
-import ai.nets.samj.utils.Constants;
-
-/**
- * Class that creates a default graphical user interface to interact with SAMJ models
- * @author Carlos Garcia
- * @author Daniel Sage
- * @author Vladimir Ulman
- */
-public class SAMJDialog extends JPanel implements ActionListener, PopupMenuListener {
-
- /**
- * Unique serial version identifier
- */
- private static final long serialVersionUID = -4362794696325316195L;
- /**
- * Name of the folder where the icon images for the dialog buttons are within the resources folder
- */
- private static final String RESOURCES_FOLDER = "icons_samj/";
- /**
- * Button that closes the GUI
- */
- private JButton bnClose = new JButton("Close");
- /**
- * Button that opens the help button
- */
- private JButton bnHelp = new JButton("Help");
- /**
- * Button that when pressed runs the SAMJ model encoder on the image selected
- */
-
- private LoadingButton bnStart;
- /** TODO will this ever happen?
- * Button for the auto-complete function, it is not ready yet
- */
- private JButton bnComplete = new JButton("Coming soon...");
- /**
- * Button to export the ROIs of an image to a instance segmentation labeling
- */
- private JButton bnRoi2Labeling = new JButton("Export as Label");
- /**
- * Text field containing copyrigth info
- */
- private JTextField txtStatus = new JTextField("(c) SAMJ team 2024 - " + Constants.SAMJ_VERSION);
- /**
- * Button that activates the annotation with SAMJ models using bounding box prompts
- */
- private ButtonIcon bnRect = new ButtonIcon("Rect", RESOURCES_FOLDER, "rect_samj.png");
- /**
- * Button that activates the annotation with SAMJ models using point or multiple points prompts
- */
- private ButtonIcon bnPoints = new ButtonIcon("Points", RESOURCES_FOLDER, "points_samj.png");
- /**
- * Button that activates the annotation with SAMJ models using freeline prompts drawn with a freeline
- */
- private ButtonIcon bnBrush = new ButtonIcon("Brush", RESOURCES_FOLDER, "brush_samj.png");
- /**
- * Button that allows selecting a mask as a prompt for the image
- */
- private ButtonIcon bnMask = new ButtonIcon("Mask", RESOURCES_FOLDER, "help_samj.png");
- /**
- * Key that specifies that the user only wants the model to return the largest ROI
- */
- private static final String ONLY_BIGGEST = "Only return largest ROI";
- /**
- * Key that specifies that the user wants to return every ROI produced by the model
- */
- private static final String ALL = "Return all ROIs";
- /**
- * Combobox to choose whether to return only the biggest ROI produced by a SAM-based model
- * or to return all what is outputed by the model
- */
- private JComboBox cmbROIs = new JComboBox(new String[] {ONLY_BIGGEST, ALL});
- /**
- * Checkbox that defines whether to add the segmentations to the roi manager or not
- */
- private JCheckBox chkROIManager = new JCheckBox("Add to ROI Manager", true);
- /**
- * Combo box containing the images that are currently open
- */
- private JComboBox cmbImage = new JComboBox();
- /**
- * Panel containing the model choice and HTML panel with info about the models or installation
- */
- private final SAMModelPanel panelModel;
- /**
- * Logger for the GUI actions
- */
- private final SAMJLogger GUIsOwnLog;
- /**
- * Logger for the SAMJ models
- */
- private final SAMJLogger logForNetworks;
- /**
- * Interface implementation that contains methods specific to each consumer software
- */
- private final UtilityMethods consumerMethods;
- /**
- * Unique identifier of the selected image
- */
- private Integer selectedID = null;
- /**
- * Functional interface that allows creating different instances of SAMJ models for different images
- */
- public interface PromptsFunctionalInterface { PromptsResultsDisplay getPrompts(Object image); }
- /**
- * Implementation of the {@link PromptsFunctionalInterface} in the consumer software that allows the consumer
- * software to provide prompts to the image of interest
- */
- private PromptsFunctionalInterface displayInterface;
- /**
- * Implementation of the {@link PromptsResultsDisplay} in the consumer software that allows the consumer
- * software to provide prompts to the image of interest
- */
- private PromptsResultsDisplay display;
- /**
- * Whether the encodings for the current image are available or the image encoder needs to be
- * run to provide annotations
- */
- private boolean encodingsDone = false;
-
- /**
- * Constructor that creates the default GUI for SAMJ. This GUI lets the user decide between
- * several SAM based models. It also lets the user install all the models with just one click.
- * Once installed the user can use any of the models to annotate providing the needed prompts
- * in the way of the consumer software.
- * @param availableModel
- * all SAM-based models available to be used
- * @param consumerMethods
- * interface implementing methods on the consumer software
- */
- public SAMJDialog(final SAMModels availableModel, UtilityMethods consumerMethods) {
- this(availableModel, consumerMethods, null, null);
- }
-
- /**
- * Constructor that creates the default GUI for SAMJ. This GUI lets the user decide between
- * several SAM based models. It also lets the user install all the models with just one click.
- * Once installed the user can use any of the models to annotate providing the needed prompts
- * in the way of the consumer software.
- * @param availableModel
- * all SAM-based models available to be used
- * @param consumerMethods
- * interface implementing methods on the consumer software
- * @param guilogger
- * interface implemented on the consumer software to log the events on the GUI
- */
- public SAMJDialog(final SAMModels availableModel,
- UtilityMethods consumerMethods,
- final SAMJLogger guilogger) {
- this(availableModel, consumerMethods, guilogger, null);
- }
-
- /**
- * Constructor that creates the default GUI for SAMJ. This GUI lets the user decide between
- * several SAM based models. It also lets the user install all the models with just one click.
- * Once installed the user can use any of the models to annotate providing the needed prompts
- * in the way of the consumer software.
- * @param availableModel
- * all SAM-based models available to be used
- * @param consumerMethods
- * interface implementing methods on the consumer software
- * @param guilogger
- * interface implemented on the consumer software to log the events on the GUI
- * @param networkLogger
- * interface implemented on the consumer software to log the SAMJ models events
- */
- public SAMJDialog(final SAMModels availableModel, UtilityMethods consumerMethods,
- final SAMJLogger guilogger,
- final SAMJLogger networkLogger) {
- // TODO super(new JFrame(), "SAMJ Annotator");
- if (guilogger == null) {
- this.GUIsOwnLog = new SAMJLogger () {
- @Override
- public void info(String text) {}
- @Override
- public void warn(String text) {}
- @Override
- public void error(String text) {}
- };
- } else {
- this.GUIsOwnLog = guilogger;
- }
- if (networkLogger == null) {
- this.logForNetworks = new SAMJLogger () {
- @Override
- public void info(String text) {}
- @Override
- public void warn(String text) {}
- @Override
- public void error(String text) {}
- };
- } else {
- this.logForNetworks = networkLogger;
- }
- this.consumerMethods = consumerMethods;
-
- panelModel = new SAMModelPanel(availableModel, (boolean bol) -> this.updateInterface(bol));
- // Buttons
- JPanel pnButtons = new JPanel(new FlowLayout());
- pnButtons.add(bnRect);
- pnButtons.add(bnPoints);
- pnButtons.add(bnBrush);
- // TODO decide what to do pnButtons.add(bnMask);
-
- // Status
- JToolBar pnStatus = new JToolBar();
- pnStatus.setFloatable(false);
- pnStatus.setLayout(new BorderLayout());
- pnStatus.add(bnHelp, BorderLayout.EAST);
- txtStatus.setEditable(false);
- pnStatus.add(txtStatus, BorderLayout.CENTER);
- pnStatus.add(bnClose, BorderLayout.WEST);
-
- JPanel pnActions = new JPanel(new FlowLayout());
- pnActions.add(bnRoi2Labeling);
- pnActions.add(bnComplete);
- pnActions.add(cmbROIs);
- pnActions.add(chkROIManager);
- // TODO think what to do with "add to roimanager" cehckbox
- chkROIManager.setEnabled(false);
-
- List listImages = this.consumerMethods.getListOfOpenImages();
- for(ComboBoxItem item : listImages)
- cmbImage.addItem(item);
- cmbImage.addPopupMenuListener(this);
-
- GridBagLayout middleLayout = new GridBagLayout();
- //middleLayout.columnWidths = new int[] {1, 5};
- middleLayout.columnWeights = new double[] {1.0, 10.0};
- middleLayout.rowHeights = new int[] {1};
- JPanel panelImage = new JPanel(middleLayout);
- panelImage.setBorder(BorderFactory.createEtchedBorder());
-
- GridBagConstraints gbc0 = new GridBagConstraints();
- gbc0.fill = GridBagConstraints.HORIZONTAL;
- gbc0.gridx = 0;
- gbc0.insets = new Insets(5, 5, 5, 0);
- bnStart = new LoadingButton("Go!", RESOURCES_FOLDER, "loading_animation_samj.gif", 20);
- panelImage.add(bnStart, gbc0);
- GridBagConstraints gbc1 = new GridBagConstraints();
- gbc1.fill = GridBagConstraints.HORIZONTAL;
- gbc1.gridx = 1;
- gbc1.insets = new Insets(5, 5, 5, 6);
- panelImage.add(cmbImage, gbc1);
- cmbImage.setPreferredSize(new Dimension(panelModel.getWidth(), 25));
-
- GridPanel pn = new GridPanel();
- pn.place(1, 1, panelModel);
- pn.place(2, 1, panelImage);
- pn.place(3, 1, pnButtons);
- pn.place(4, 1, pnActions);
-
- setLayout(new BorderLayout());
- add(pn, BorderLayout.NORTH);
- add(pnStatus, BorderLayout.SOUTH);
-
- bnRoi2Labeling.addActionListener(this);
- // TODO not ready yet bnComplete.addActionListener(this);
- bnRoi2Labeling.setEnabled(false);
- bnComplete.setEnabled(false);
- bnClose.addActionListener(this);
- bnHelp.addActionListener(this);
- chkROIManager.addActionListener(this);
- cmbROIs.addPopupMenuListener(this);
-
- bnStart.addActionListener(this);
- bnRect.addActionListener(this);
- bnPoints.addActionListener(this);
- bnBrush.addActionListener(this);
- // TODO decide what to do bnMask.addActionListener(this);
- // TODO decide what to do bnMask.setDropTarget(new LocalDropTarget());
-
- add(pn);
- updateInterface();
- }
-
- /**
- * Set the implementation of {@link PromptsFunctionalInterface} in the consumer software that allows working with
- * image objects native to the consumer software
- * @param pp
- * the implementation of {@link PromptsFunctionalInterface} in the consumer software
- */
- public void setPromptsProvider(PromptsFunctionalInterface pp) {
- this.displayInterface = pp;
- }
-
- /**
- *
- * @return the {@link SamEnvManagerAbstract} used to install and manage the models
- */
- public SamEnvManagerAbstract getModelInstallationManager() {
- return this.panelModel.getInstallationManager();
- }
-
- @Override
- /**
- * Method that controls that the logic of the buttons is correct
- */
- public void actionPerformed(ActionEvent e) {
-
- if (e.getSource() == bnRect && !bnRect.isSelected()) {
- display.switchToUsingRectangles();
- bnRect.setPressed(true); bnPoints.setPressed(false); bnBrush.setPressed(false);
- } else if (e.getSource() == bnPoints && !bnPoints.isSelected()) {
- display.switchToUsingPoints();
- bnRect.setPressed(false); bnPoints.setPressed(true); bnBrush.setPressed(false);
- } else if (e.getSource() == bnBrush && !bnBrush.isSelected()) {
- display.switchToUsingBrush();
- bnRect.setPressed(false); bnPoints.setPressed(false); bnBrush.setPressed(true);
- } else if (e.getSource() == bnRect || e.getSource() == bnPoints || e.getSource() == bnBrush) {
- display.switchToNone();
- bnRect.setPressed(false); bnPoints.setPressed(false); bnBrush.setPressed(false);
- } else if (e.getSource() == bnHelp) {
- Tools.help();
- } else if (e.getSource() == bnClose) {
- this.close();
- } else if (e.getSource() == bnComplete) {
- GUIsOwnLog.warn("TO DO call Auto-complete");
- } else if (e.getSource() == bnStart) {
- if (!panelModel.getSelectedModel().isInstalled())
- GUIsOwnLog.warn("Not starting encoding as the selected model is not installed.");
-
- GUIsOwnLog.warn("Start the encoding");
- if (display == null
- || !display.getFocusedImage().equals(((ComboBoxItem) this.cmbImage.getSelectedItem()).getValue())) {
- display = displayInterface.getPrompts(((ComboBoxItem) this.cmbImage.getSelectedItem()).getValue());
- display.setRectIconConsumer(b -> this.bnRect.setPressed(b));
- display.setFreelineIconConsumer(b -> this.bnBrush.setPressed(b));
- display.setPointsIconConsumer(b -> this.bnPoints.setPressed(b));
- }
- SAMModel selectedSAMModel = this.panelModel.getSelectedModel();
- this.bnStart.setPressed(true);
- new Thread(() -> {
- SAMModel netAdapter = null;
- SwingUtilities.invokeLater(() -> {
- panelModel.bnUninstall.setEnabled(false);
- panelModel.bnInstall.setEnabled(false);
- panelModel.rbModels.stream().forEach(btn -> btn.setEnabled(false));
- panelModel.progressInstallation.setIndeterminate(true);
- });
- try {
- netAdapter = panelModel.getSelectedModel();
- netAdapter.setImage(display.giveProcessedSubImage(selectedSAMModel), logForNetworks);
- netAdapter.setReturnOnlyBiggest(cmbROIs.getSelectedItem().equals(ONLY_BIGGEST));
- } catch (Exception ex) {
- display.notifyException(SAMJException.ENCODING, ex);
- netAdapter = null;
- }
- SwingUtilities.invokeLater(() -> {
- this.bnStart.setPressed(false);
- panelModel.bnUninstall.setEnabled(panelModel.getSelectedModel().isInstalled());
- panelModel.bnInstall.setEnabled(!panelModel.getSelectedModel().isInstalled());
- panelModel.rbModels.stream().forEach(btn -> btn.setEnabled(true));
- panelModel.progressInstallation.setIndeterminate(false);
- panelModel.progressInstallation.setValue(100);
- });
- if (netAdapter == null) return;
- display.switchToThisNet(netAdapter);
- GUIsOwnLog.warn("Finished the encoding");
- SwingUtilities.invokeLater(() -> {
- //TODO: encoding should be a property of a model
- this.setEncodingsDone(true);
- updateInterface();
- });
- }).start();
- return;
- } else if (e.getSource() == chkROIManager) {
- if (display != null)
- display.enableAddingToRoiManager(chkROIManager.isSelected());
- } else if (e.getSource() == this.bnMask) {
- JFileChooser fileChooser = new JFileChooser();
- int returnValue = fileChooser.showOpenDialog(null);
- if (returnValue == JFileChooser.APPROVE_OPTION) {
- this.display.improveExistingMask(fileChooser.getSelectedFile());
- }
- } else if (e.getSource() == this.bnRoi2Labeling) {
- this.display.exportImageLabeling();
- }
-
- updateInterface();
- }
-
- /**
- * Update the interface
- */
- public void updateInterface() {
- updateInterface(false);
- }
-
- /**
- * Update the interface deleting the encodings and current Python process if needed
- * @param deleteEncodings
- * whether to delete or not the current encodings and the current Python process
- */
- public void updateInterface(boolean deleteEncodings) {
- if (deleteEncodings) this.setEncodingsDone(false);
- if (!this.panelModel.isSelectedModelInstalled()) {
- this.bnStart.setEnabled(false);
- this.cmbImage.setEnabled(false);
- setEncodingsDone(false);
- } else if (this.panelModel.isSelectedModelInstalled()
- && !this.encodingsDone
- && this.cmbImage.getSelectedItem() != null
- && ((ComboBoxItem) this.cmbImage.getSelectedItem()).getId() != -1) {
- this.bnStart.setEnabled(true);
- this.cmbImage.setEnabled(true);
- // TODO think what to do this.chkROIManager.setEnabled(true);
- this.cmbROIs.setEnabled(true);
- } else if (this.panelModel.isSelectedModelInstalled()
- && this.cmbImage.getSelectedItem() != null
- && ((ComboBoxItem) this.cmbImage.getSelectedItem()).getId() != -1) {
- this.bnStart.setEnabled(false);
- this.cmbImage.setEnabled(true);
- } else if (this.panelModel.isSelectedModelInstalled()) {
- this.bnStart.setEnabled(false);
- this.cmbImage.setEnabled(true);
- }
- // TODO not ready yet bnComplete.setEnabled(this.encodingsDone);
- bnRoi2Labeling.setEnabled(this.encodingsDone);
- // TODO think what to do chkROIManager.setEnabled(this.encodingsDone);
- cmbROIs.setEnabled(this.encodingsDone);
- bnRect.setEnabled(this.encodingsDone);
- bnPoints.setEnabled(this.encodingsDone);
- bnBrush.setEnabled(this.encodingsDone);
- bnMask.setEnabled(this.encodingsDone);
- if (!encodingsDone) {
- this.bnRect.setPressed(false);
- this.bnPoints.setPressed(false);
- this.bnBrush.setPressed(false);
- this.bnMask.setPressed(false);
- }
- }
-
- /**
- * Set whether the encodings for the current image have been already calculated or not.
- * If true, the encodings for the selected image do not need to be calculated until the iuser
- * selects another image
- * @param isDone
- * whether the encodings for the current image have been calculated or not
- */
- private void setEncodingsDone(boolean isDone) {
- this.encodingsDone = isDone;
- if (!isDone) {
- if (display != null) {
- display.notifyNetToClose();
- display.switchToNone();
- }
- this.bnRect.setPressed(false);
- this.bnPoints.setPressed(false);
- this.bnBrush.setPressed(false);
- this.bnMask.setPressed(false);
- }
- }
-
- /**
- * Class that implements drag and drop for the mask prompt
- */
- public class LocalDropTarget extends DropTarget {
-
- private static final long serialVersionUID = 286813958463411816L;
-
- @Override
- /**
- * Enable drag and drop on the mask prompt button and calculate the annotation once the
- * mask is dropped
- */
- public void drop(DropTargetDropEvent e) {
- e.acceptDrop(DnDConstants.ACTION_COPY);
- e.getTransferable().getTransferDataFlavors();
- Transferable transferable = e.getTransferable();
- DataFlavor[] flavors = transferable.getTransferDataFlavors();
- for (DataFlavor flavor : flavors) {
- if (flavor.isFlavorJavaFileListType()) {
- try {
- List files = (List) transferable.getTransferData(flavor);
- for (File file : files) {
- GUIsOwnLog.info("Taking mask from file " + file.getAbsolutePath());
- display.improveExistingMask(file);
- }
- }
- catch (UnsupportedFlavorException ex) {
- ex.printStackTrace();
- }
- catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
- e.dropComplete(true);
- super.drop(e);
- }
- }
-
- /**
- * Close the panel and the plugin, deleting the python process if it exists
- */
- public void close() {
- if (display != null) {
- display.notifyNetToClose();
- display.switchToNone();
- }
- display = null;
- this.panelModel.interrupExistingThreads();
- if (SwingUtilities.windowForComponent(this).isDisplayable())
- SwingUtilities.windowForComponent(this).dispose();
- }
-
- @Override
- /**
- * Update the list of images opened once the combobox pop up is open
- */
- public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
- if (e.getSource() == this.cmbROIs) return;
- Object item = this.cmbImage.getSelectedItem();
- List openSeqs = consumerMethods.getListOfOpenImages();
- ComboBoxItem[] objects = new ComboBoxItem[openSeqs.size()];
- for (int i = 0; i < objects.length; i ++) objects[i] = openSeqs.get(i);
- DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(objects);
- this.cmbImage.setModel(comboBoxModel);
- if (item != null && objects.length != 0)
- this.cmbImage.setSelectedIndex(
- IntStream.range(0, objects.length).filter(i -> objects[i].getId() == ((ComboBoxItem) item).getId()).findFirst().orElse(0)
- );
- }
-
- @Override
- /**
- * Check if the image selected has been changed once the combobox pop up is closed
- */
- public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
- if (e.getSource() == this.cmbROIs) {
- if (display != null)
- display.getNetBeingUsed().setReturnOnlyBiggest(cmbROIs.getSelectedItem().equals(ONLY_BIGGEST));
- return;
- }
- ComboBoxItem item = (ComboBoxItem) this.cmbImage.getSelectedItem();
- if ( item == null || (item != null && item.getId() == -1) ) {
- setEncodingsDone(false);
- selectedID = null;
- } else if (selectedID == null || (selectedID != null && selectedID != item.getId())) {
- setEncodingsDone(false);
- selectedID = item.getId();
- }
- this.updateInterface();
- }
-
- @Override
- /**
- * Nothing
- */
- public void popupMenuCanceled(PopupMenuEvent e) {
- }
-}
diff --git a/src/main/java/ai/nets/samj/gui2/SAMModelPanel.java b/src/main/java/ai/nets/samj/gui2/SAMModelPanel.java
deleted file mode 100644
index 40b9a23..0000000
--- a/src/main/java/ai/nets/samj/gui2/SAMModelPanel.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/*-
- * #%L
- * Library to call models of the family of SAM (Segment Anything Model) from Java
- * %%
- * Copyright (C) 2024 SAMJ developers.
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-package ai.nets.samj.gui;
-
-import java.awt.BorderLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.IOException;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Objects;
-
-import javax.swing.ButtonGroup;
-import javax.swing.JButton;
-import javax.swing.JPanel;
-import javax.swing.JProgressBar;
-import javax.swing.JRadioButton;
-import javax.swing.JScrollPane;
-import javax.swing.JToolBar;
-import javax.swing.SwingUtilities;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.html.HTMLDocument;
-import javax.swing.text.html.HTMLEditorKit;
-
-import ai.nets.samj.communication.model.SAMModel;
-import ai.nets.samj.communication.model.SAMModels;
-import ai.nets.samj.gui.components.GridPanel;
-import ai.nets.samj.gui.components.HTMLPane;
-import ai.nets.samj.install.SamEnvManagerAbstract;
-import io.bioimage.modelrunner.apposed.appose.Mamba;
-
-/**
- * Class that creates a subpanel in the main panel of SAMJ default GUI.
- * This panel handles model selection and installation.
- * @author Carlos Garcia
- * @author Daniel Sage
- * @author Vladimir Ulman
- */
-public class SAMModelPanel extends JPanel implements ActionListener {
- /**
- * Unique serial identifier
- */
- private static final long serialVersionUID = 7623385356575804931L;
- /**
- * HTML panel where all the info about models and installation is going to be shown
- */
- private HTMLPane info = new HTMLPane(450, 135);
- /**
- * Parameter used in the HTML panel during installation to know when to update
- */
- private int waitingIter = 0;
- /**
- * Button that when clicked installs the model selected
- */
- protected JButton bnInstall = new JButton("Install");
- /**
- * Button that when clicked uninstalls the model selected
- */
- protected JButton bnUninstall = new JButton("Uninstall");
- /**
- * Progress bar used during the model installation. If the model is already installed it
- * is full, if it is not it is empty
- */
- protected JProgressBar progressInstallation = new JProgressBar();
- /**
- * List of radio buttons that point to the models available
- */
- protected ArrayList rbModels = new ArrayList();
- /**
- * Object contianing a list of the models available, and whether they are selected, installed...
- */
- private SAMModels models;
- /**
- * Index of hte selected model in the list of available models
- */
- private int selectedModel = 0;
- /**
- * Whether the model selected has changed or not
- */
- private boolean modelChanged = false;
- /**
- * Time format using to update the installation information
- */
- private static DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss");
- /**
- * Interface implemented at {@link SAMJDialog} to tell the parent JPanel to update the
- * interface
- */
- interface CallParent {
- /**
- * The implemented task to be done at {@link SAMJDialog}
- * @param bool
- * some helper parameter
- */
- public void task(boolean bool);
- }
- /**
- * Implementation of the interface {@link CallParent}
- */
- private CallParent updateParent;
- /**
- * Thread used to install a model
- */
- protected Thread installationThread;
- /**
- * Thread used to check the models that are installed
- */
- protected Thread checkingThread;
-
- /**
- * Constructor of the class. Creates a panel that contains the selection of available models
- * and an html panel with info about the models that also displays the installation progress
- * when the model is being installed
- * @param models
- * list of models that are available
- * @param updateParent
- * interface implementation on {@link SAMJDialog} that allows making modifications in the parent GUI
- */
- public SAMModelPanel(SAMModels models, CallParent updateParent) {
- super();
- this.updateParent = updateParent;
- this.models = models;
- JToolBar pnToolbarModel = new JToolBar();
- pnToolbarModel.setFloatable(false);
- pnToolbarModel.setLayout(new GridLayout(1, 2));
- pnToolbarModel.add(bnInstall);
- pnToolbarModel.add(bnUninstall);
-
- ButtonGroup group = new ButtonGroup();
- for(SAMModel model : models) {
- model.getInstallationManger().setConsumer((str) -> addHtml(str));
- JRadioButton rb = new JRadioButton(model.getName(), false);
- rbModels.add(rb);
- rb.addActionListener(this);
- group.add(rb);
- }
- rbModels.get(0).setSelected(true);
-
- JPanel pnManageModel = new JPanel(new BorderLayout());
- pnManageModel.add(pnToolbarModel, BorderLayout.NORTH);
- pnManageModel.add(progressInstallation, BorderLayout.SOUTH);
- pnManageModel.add(new JScrollPane(info), BorderLayout.CENTER);
-
- GridPanel pnModel = new GridPanel(true);
- int col = 1;
- for(JRadioButton rb : rbModels)
- pnModel.place(1, col++, 1, 1, rb);
-
- pnModel.place(2, 1, 6, 2, pnManageModel);
-
- add(pnModel);
- info.append("p", "Description of the model");
- info.append("p", "Link to source");
- bnInstall.addActionListener(this);
- bnUninstall.addActionListener(this);
-
- updateInterface();
- checkInstalledModelsThread();
- checkingThread.start();
- Thread reportThread = reportHelperThread(checkingThread);
- reportThread.start();
- }
-
- private void checkInstalledModelsThread() {
- boolean isEDT = SwingUtilities.isEventDispatchThread();
- checkingThread= new Thread(() -> {
- if (isEDT) {
- SwingUtilities.invokeLater(() -> {
- this.info.clear();
- this.installationInProcess(true);
- this.info.append("FINDING INSTALLED MODELS");
- });
- } else {
- this.info.clear();
- this.addHtml("FINDING INSTALLED MODELS");
- this.installationInProcess(true);
- }
- for(SAMModel model : models) {
- if (Thread.currentThread().isInterrupted()) return;
- model.setInstalled(model.getInstallationManger().checkEverythingInstalled());
- }
-
- if (isEDT) {
- SwingUtilities.invokeLater(() -> {
- this.installationInProcess(false);
- rbModels.get(0).setSelected(true);
- updateInterface();
- this.updateParent.task(false);
- });
- } else {
- this.installationInProcess(false);
- rbModels.get(0).setSelected(true);
- updateInterface();
- this.updateParent.task(false);
- }
-
- });
- }
-
- private void updateInterface() {
- for(int i=0; i {
- try {
- SwingUtilities.invokeLater(() -> installationInProcess(true));
- this.getSelectedModel().getInstallationManger().installEverything();
- getSelectedModel().setInstalled(true);
- SwingUtilities.invokeLater(() -> {
- installationInProcess(false);
- this.updateParent.task(false);});
- } catch (Exception e1) {
- e1.printStackTrace();
- SwingUtilities.invokeLater(() -> {installationInProcess(false); this.updateParent.task(false);});
- }
- });
- }
-
- @Override
- /**
- * Mange the interface actions and logic
- */
- public void actionPerformed(ActionEvent e) {
-
- if (e.getSource() == bnInstall) {
- createInstallationThread();
- this.installationThread.start();
- // TODO remove Thread controlThread = createControlThread(installThread);
- // TODO remove controlThread.start();
- } else if (e.getSource() == bnUninstall) {
- Thread uninstallThread = createUninstallThread();
- uninstallThread.start();
- Thread reportThread = reportHelperThread(uninstallThread);
- reportThread.start();
- // TODO remove Thread controlThread = createControlThread(uninstallThread);
- // TODO remove controlThread.start();
- }
-
- updateInterface();
- this.updateParent.task(modelChanged);
- modelChanged = false;
- }
-
- /**
- * Create thread in charge of reporting that there is an action in progress
- * @param importantThread
- * the thread where the process happens
- * @return the thread that keeps the reporting so the user does not think that the activity stopped
- */
- private Thread reportHelperThread(Thread importantThread) {
-
- Thread t = new Thread(() -> {
- try { Thread.sleep(300); } catch (InterruptedException e) { return; }
- while (importantThread.isAlive()) {
- addHtml("");
- try { Thread.sleep(300); } catch (InterruptedException e) { return; }
- }
- SwingUtilities.invokeLater(() -> updateInterface());
- });
- return t;
- }
-
- /**
- * Create the Thread that is used to uninstall the selected model
- * @return the thread where the models will be installed
- */
- private Thread createUninstallThread() {
- Thread installThread = new Thread(() -> {
- this.getSelectedModel().setInstalled(false);
- try {
- SwingUtilities.invokeLater(() -> {
- this.info.clear();
- this.addHtml("UNINSTALL MODEL");
- installationInProcess(true);
- this.updateParent.task(true);
- });
- uninstallModel();
- SwingUtilities.invokeLater(() -> {
- installationInProcess(false);});
- } catch (Exception e1) {
- e1.printStackTrace();
- SwingUtilities.invokeLater(() -> {installationInProcess(false); this.updateParent.task(false);});
- }
- });
- return installThread;
- }
-
- /**
- * Uninstall the model from the user computer. Delete the required files
- */
- private void uninstallModel() {
- try {
- Thread.sleep(10000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- getSelectedModel().getInstallationManger().uninstall();
- getSelectedModel().setInstalled(false);
- }
-
- /**
- * Update the interface accordingly once the installation starts or finishes
- * @param inProcess
- * whether the installation is happening or it has finished already
- */
- private void installationInProcess(boolean inProcess) {
- info.clear();
- this.bnUninstall.setEnabled(inProcess ? false : getSelectedModel().isInstalled());
- this.bnInstall.setEnabled(inProcess ? false : !getSelectedModel().isInstalled());
- this.rbModels.stream().forEach(btn -> btn.setEnabled(!inProcess));
- this.progressInstallation.setIndeterminate(inProcess);
- if (!inProcess) {
- this.progressInstallation.setValue(this.getSelectedModel().isInstalled() ? 100 : 0);
- this.updateInterface();
- }
- }
-
- /**
- * Sets the HTML text to be displayed.
- *
- * @param html
- * HTML text.
- * @throws NullPointerException
- * If the HTML text is null.
- */
- public void setHtml(String html) throws NullPointerException
- {
- Objects.requireNonNull(html, "HTML text is null");
- info.setText(formatHTML(html));
- info.setCaretPosition(0);
- }
-
- /**
- * Sets the HTML text to be displayed and moves the caret until the end of the text
- *
- * @param html
- * HTML text.
- * @throws NullPointerException
- * If the HTML text is null.
- */
- public void setHtmlAndDontMoveCaret(String html) throws NullPointerException {
- Objects.requireNonNull(html, "HTML text is null");
- HTMLDocument doc = (HTMLDocument) info.getDocument();
- HTMLEditorKit editorKit = (HTMLEditorKit) info.getEditorKit();
- try {
- doc.remove(0, doc.getLength());
- editorKit.insertHTML(doc, doc.getLength(), formatHTML(html), 0, 0, null);
- } catch (BadLocationException | IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * @return HTML text shown in this component.
- */
- public String getHtml()
- {
- return info.getText();
- }
-
- /**
- * Add a String to the html pane in the correct format
- * @param html
- * the String to be converted into HTML and added to the HTML panel
- */
- public void addHtml(String html) {
- if (html == null) return;
- if (html.trim().isEmpty()) {
- html = manageEmptyMessage(html);
- } else {
- waitingIter = 0;
- }
- String nContent = formatHTML(html);
-
- SwingUtilities.invokeLater(() -> {
- try {
- HTMLDocument doc = (HTMLDocument) info.getDocument();
- HTMLEditorKit editorKit = (HTMLEditorKit) info.getEditorKit();
- editorKit.insertHTML(doc, doc.getLength(), nContent, 0, 0, null);
- info.setCaretPosition(doc.getLength());
- } catch (Exception e) {
- e.printStackTrace();
- }
- });
- }
-
- /**
- * Convert the input String into the correct HTML string for the HTML panel
- * @param html
- * the input Stirng to be formatted
- * @return the String formatted into the correct HTML string
- */
- private static String formatHTML(String html) {
- html = html.replace(System.lineSeparator(), "
")
- .replace(" ", " ")
- .replace(" ", " ")
- .replace(" ", " ");
-
- if (html.startsWith(Mamba.ERR_STREAM_UUUID)) {
- html = "" + html.replace(Mamba.ERR_STREAM_UUUID, "") + "";
- } else {
- html = "" + html + "";
- }
- return html;
- }
-
- /**
- * Check if a message is empty, thus no information is comming. If the message is not empty, nothing is done.
- * If it is, the html panel is updated so a changing installation in progress message appears
- * @param html
- * the message sent by the installation thread
- * @return the message to be print in the html panel
- */
- private String manageEmptyMessage(String html) {
- String working = "Working, this might take several minutes";
- if (html.trim().isEmpty() && waitingIter == 0) {
- html = LocalDateTime.now().format(DATE_FORMAT).toString() + " -- " + working + " .";
- waitingIter += 1;
- } else if (html.trim().isEmpty() && waitingIter % 3 == 1) {
- html = LocalDateTime.now().format(DATE_FORMAT).toString() + " -- " + working + " . .";
- int len = html.length() - (" .").length() + System.lineSeparator().length();
- SwingUtilities.invokeLater(() -> {
- HTMLDocument doc = (HTMLDocument) info.getDocument();
- try {doc.remove(doc.getLength() - len, len);} catch (BadLocationException e) {}
- });
- waitingIter += 1;
- } else if (html.trim().isEmpty() && waitingIter % 3 == 2) {
- html = LocalDateTime.now().format(DATE_FORMAT).toString() + " -- " + working + " . . .";
- int len = html.length() - (" .").length() + System.lineSeparator().length();
- SwingUtilities.invokeLater(() -> {
- HTMLDocument doc = (HTMLDocument) info.getDocument();
- try {doc.remove(doc.getLength() - len, len);} catch (BadLocationException e) {}
- });
- waitingIter += 1;
- } else if (html.trim().isEmpty() && waitingIter % 3 == 0) {
- html = LocalDateTime.now().format(DATE_FORMAT).toString() + " -- " + working + " .";
- int len = html.length() + (" . .").length() + System.lineSeparator().length();
- SwingUtilities.invokeLater(() -> {
- HTMLDocument doc = (HTMLDocument) info.getDocument();
- try {doc.remove(doc.getLength() - len, len);} catch (BadLocationException e) {}
- });
- waitingIter += 1;
- }
- return html;
- }
-
- /**
- * Tries to interrupt any thread that might be runnning
- */
- public void interrupExistingThreads() {
- if (this.checkingThread != null && this.checkingThread.isAlive())
- this.checkingThread.interrupt();
- if (this.installationThread != null && this.installationThread.isAlive())
- this.installationThread.interrupt();
- }
-}
-
-
diff --git a/src/main/java/ai/nets/samj/gui2/icons/ButtonIcon.java b/src/main/java/ai/nets/samj/gui2/icons/ButtonIcon.java
deleted file mode 100644
index dddc2fe..0000000
--- a/src/main/java/ai/nets/samj/gui2/icons/ButtonIcon.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-
- * #%L
- * Library to call models of the family of SAM (Segment Anything Model) from Java
- * %%
- * Copyright (C) 2024 SAMJ developers.
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-package ai.nets.samj.gui.icons;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Image;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.security.CodeSource;
-import java.security.ProtectionDomain;
-
-import javax.swing.BorderFactory;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.SwingConstants;
-/**
- * ButtonIcon class represents a custom JButton with icons for normal and pressed states.
- * @author Carlos Garcia
- * @author Daniel Sage
- */
-public class ButtonIcon extends JButton {
-
- /**
- * Serial version unique identifier
- */
- private static final long serialVersionUID = 7396676607184967666L;
- /**
- * Prefix used in the file name of the images that represent that the button is pressed.
- */
- private static final String PRESSED_PREFIX = "pressed_";
- /**
- * Icon for when the button is not pressed
- */
- private ImageIcon normalIcon;
- /**
- * Icon for when the button is pressed
- */
- private ImageIcon pressedIcon;
- /**
- * String that is displayed inside the button
- */
- private String text;
- /**
- * Original color of the buttons
- */
- private Color color;
- /**
- * HTML used to format the button label text. First the color needs to be specified, then the
- * text that wants to be in the button
- */
- private static final String BTN_TEXT_HTML = "%s";
- /**
- * Color code for the HTML String of the button for when the button is not pressed
- */
- private static final String NOT_PRESSED_COLOR = "black";
- /**
- * Color code for the HTML String of the button for when the button is pressed
- */
- private static final String PRESSED_COLOR = "white";
-
- /**
- * Constructor. Creates a button that has an icon inside. The icon changes when pressed.
- * @param text
- * the text inside the button
- * @param filePath
- * the path to the file that contains the image that is going to be used
- * @param filename
- * the name of the file that is going to be used
- */
- public ButtonIcon(String text, String filePath, String filename) {
- super();
- this.text = text;
- try {
- normalIcon = getIcon(filePath + "/" + filename);
- pressedIcon = getIcon(filePath + "/" + PRESSED_PREFIX + filename);
- if (normalIcon != null) {
- setIcon(normalIcon);
- setBorder(BorderFactory.createEtchedBorder());
- setOpaque(false);
- setContentAreaFilled(false);
- setPreferredSize(new Dimension(58, 58));
- setVerticalTextPosition(SwingConstants.BOTTOM);
- setHorizontalTextPosition(SwingConstants.CENTER);
- setText(String.format(BTN_TEXT_HTML, NOT_PRESSED_COLOR, text));
- }
- if (pressedIcon != null) {
- this.setPressedIcon(pressedIcon);
- }
- }
- catch (Exception ex) {
- setText(text);
- }
- color = this.getBackground();
- }
-
- private ImageIcon getIcon(String path) {
- while (path.indexOf("//") != -1) path = path.replace("//", "/");
- URL url = ButtonIcon.class.getClassLoader().getResource(path);
- if (url == null) {
- File f = findJarFile(ButtonIcon.class);
- if (f.getName().endsWith(".jar")) {
- try (URLClassLoader clsloader = new URLClassLoader(new URL[]{f.toURI().toURL()})){
- url = clsloader.getResource(path);
- } catch (IOException e) {
- }
- }
- }
- if (url != null) {
- ImageIcon img = new ImageIcon(url) ;
- Image image = img.getImage();
- Image scaled = image.getScaledInstance(32, 32, Image.SCALE_SMOOTH);
- return new ImageIcon(scaled);
- }
- return null;
- }
-
- private static File findJarFile(Class> clazz) {
- ProtectionDomain protectionDomain = clazz.getProtectionDomain();
- if (protectionDomain != null) {
- CodeSource codeSource = protectionDomain.getCodeSource();
- if (codeSource != null) {
- URL location = codeSource.getLocation();
- if (location != null) {
- try {
- return new File(URI.create(location.toURI().getSchemeSpecificPart()).getPath());
- } catch (URISyntaxException e) {
- e.printStackTrace();
- }
- }
- }
- }
- return null;
- }
-
- /**
- * Set the button as pressed or not pressed, changing the image displayed
- * @param isPressed
- * whether the button is pressed or not
- */
- public void setPressed(boolean isPressed) {
- if (isPressed) {
- this.setIcon(pressedIcon);
- this.setBackground(Color.BLACK);
- this.setOpaque(true);
- this.setContentAreaFilled(true);
- } else {
- this.setIcon(normalIcon);
- this.setBackground(color);
- this.setOpaque(false);
- }
-
- setText(String.format(BTN_TEXT_HTML, isPressed ? PRESSED_COLOR : NOT_PRESSED_COLOR, text));
-
- this.setSelected(isPressed);
- this.validate();
- this.repaint();
- }
-}