gt:             addRegion(new Region(name, color));
context: /*
   *  IJ-Plugins
   *  Copyright (C) 2002-2021 Jarek Sacha
   *  Author's email: jpsacha at gmail dot com
   *
   *  This library is free software; you can redistribute it and/or
   *  modify it under the terms of the GNU Lesser General Public
   *  License as published by the Free Software Foundation; either
   *  version 2.1 of the License, or (at your option) any later version.
   *
   *  This library is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   *  Lesser General Public License for more details.
   *
   *  You should have received a copy of the GNU Lesser General Public
   *  License along with this library; if not, write to the Free Software
   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   *  Latest release available at https://github.com/ij-plugins/ijp-toolkit/
   */
  
  package ij_plugins.toolkit.ui.multiregion;
  
  import com.jgoodies.common.collect.ArrayListModel;
  import ij.ImageListener;
  import ij.ImagePlus;
  import ij.WindowManager;
  import ij.gui.Overlay;
  import ij.gui.Roi;
  import ij.gui.ShapeRoi;
  import ij_plugins.toolkit.beans.AbstractModel;
  import ij_plugins.toolkit.ui.AbstractModelAction;
  import ij_plugins.toolkit.ui.ShapeUtils;
  import ij_plugins.toolkit.ui.UIUtils;
  import ij_plugins.toolkit.util.IJUtils;
  
  import javax.swing.*;
  import javax.swing.event.ListDataEvent;
  import javax.swing.event.ListDataListener;
  import java.awt.*;
  import java.awt.event.ActionEvent;
  import java.awt.geom.Area;
  import java.util.ArrayList;
  import java.util.List;
  
  
  /**
   * Presentation model for a MultiRegionManager view.
   *
   * @author Jarek Sacha
   */
  public final class MultiRegionManagerModel extends AbstractModel {
  
      // FIXME: A specific ImagePlus should be selected and remembered, rather than accessed by UIUtils.getImage().
  
      private static final Color[] COLORS = {
              Color.GREEN, Color.RED, Color.BLUE, Color.YELLOW, Color.CYAN, Color.MAGENTA, Color.ORANGE, Color.PINK,
      };
      private int colorCount;
      private static final int OVERLAY_ALPHA = 128;
  
      private Component parent;
  
      private final ArrayListModel<Region> regions = new ArrayListModel<>();
  
      private Region selectedRegion;
      private SubRegion selectedSubRegion;
      private ImagePlus lastSourceImage;
      private int regionCount = 1;
  
  
      public MultiRegionManagerModel() {
  
          regions.addListDataListener(new ListListener());
  
          addRegion(new Region("Background", nextColor()));
          addRegion(new Region("Region-" + regionCount++, nextColor()));
  
          // Monitor GUI for possible changes to lastSourceImage
          ImagePlus.addImageListener(new ImageListener() {
              @Override
              public void imageOpened(final ImagePlus imp) {
                  if (lastSourceImage == imp) {
                      updateShapes(lastSourceImage);
                  }
              }
  
  
              @Override
              public void imageClosed(final ImagePlus imp) {
                  if (lastSourceImage == imp) {
                      lastSourceImage = null;
                  }
              }
  
  
              @Override
              public void imageUpdated(final ImagePlus imp) {
                  if (lastSourceImage == imp) {
                      updateShapes(lastSourceImage);
                  }
              }
          });
      }
  
  
      public ArrayListModel<Region> getRegions() {
          return regions;
      }
  
  
      public Region getSelectedRegion() {
          return selectedRegion;
      }
  
  
      public void setSelectedRegion(final Region selectedRegion) {
          firePropertyChange("selectedRegion", this.selectedRegion, this.selectedRegion = selectedRegion);
      }
  
  
      public SubRegion getSelectedSubRegion() {
          return selectedSubRegion;
      }
  
  
      public void setSelectedSubRegion(final SubRegion selectedSubRegion) {
          firePropertyChange("selectedSubRegion", this.selectedSubRegion, this.selectedSubRegion = selectedSubRegion);
      }
  
  
      void setParent(final Component parent) {
          firePropertyChange("parent", this.parent, this.parent = parent);
      }
  
  
      Action createNewRegionAction() {
          return new AbstractModelAction<MultiRegionManagerModel>("Add Current ROI", this) {
              private static final long serialVersionUID = 1L;
  
  
              @Override
              public void actionPerformed(final ActionEvent e) {
                  getModel().actionAddRegion();
              }
          };
      }
  
  
      Action createRemoveRegionAction() {
          return new AbstractModelAction<MultiRegionManagerModel>("Remove", this) {
              private static final long serialVersionUID = 1L;
  
  
              @Override
              public void actionPerformed(final ActionEvent e) {
                  getModel().actionRemoveRegion();
              }
  
  
              @Override
              public boolean isEnabled() {
                  return super.isEnabled() && getModel().getSelectedRegion() != null;
              }
          };
      }
  
  
      Action createAddCurrentROIAction() {
          return new AbstractModelAction<MultiRegionManagerModel>("Add Current ROI", this) {
              private static final long serialVersionUID = 1L;
  
  
              @Override
              public void actionPerformed(final ActionEvent e) {
                  getModel().actionAddSubRegion();
              }
  
  
              @Override
              public boolean isEnabled() {
                  return super.isEnabled() && getModel().getSelectedRegion() != null;
              }
          };
      }
  
  
      Action createRemoveSubRegionAction() {
          return new AbstractModelAction<MultiRegionManagerModel>("Remove ROI", this) {
              private static final long serialVersionUID = 1L;
  
  
              @Override
              public void actionPerformed(final ActionEvent e) {
                  getModel().actionRemoveSubRegion();
              }
  
  
              @Override
              public boolean isEnabled() {
                  return super.isEnabled() && getModel().getSelectedSubRegion() != null;
              }
          };
      }
  
  
      Action createRedrawOverlaysAction() {
          return new AbstractModelAction<MultiRegionManagerModel>("Redraw Overlays", this) {
              private static final long serialVersionUID = 1L;
  
  
              @Override
              public void actionPerformed(final ActionEvent e) {
                  updateShapes(WindowManager.getCurrentImage());
              }
  
  
              @Override
              public boolean isEnabled() {
                  return super.isEnabled() && getModel().getRegions().size() > 0;
              }
          };
      }
  
  
      Action createRemoveOverlaysAction() {
          return new AbstractModelAction<MultiRegionManagerModel>("Remove Overlays", this) {
              private static final long serialVersionUID = 1L;
  
  
              @Override
              public void actionPerformed(final ActionEvent e) {
                  updateShapes(null);
              }
          };
      }
  
  
      void actionAddRegion() {
          final String name = JOptionPane.showInputDialog(parent, "Enter new object name", "Region-" + regionCount++);
          if (name != null && !name.trim().isEmpty()) {
              final Color rc = nextColor();
              final Color color = new Color(rc.getRed(), rc.getGreen(), rc.getBlue(), OVERLAY_ALPHA);
  