@Override
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == imageView) {
      selectedView = imageView.getSelectedIndex();
      owner.viewUpdated();
    } else if (e.getSource() == showCorners) {
      bShowCorners = showCorners.isSelected();
      owner.viewUpdated();
    } else if (e.getSource() == showLines) {
      bShowLines = showLines.isSelected();
      owner.viewUpdated();
    } else if (e.getSource() == showContour) {
      bShowContour = showContour.isSelected();
      owner.viewUpdated();
    } else if (e.getSource() == refineChoice) {
      refineType = PolygonRefineType.values()[refineChoice.getSelectedIndex()];

      updateRefineSettings();
      owner.configUpdate();
    } else if (e.getSource() == setConvex) {
      config.convex = setConvex.isSelected();
      owner.configUpdate();
    } else if (e.getSource() == setBorder) {
      config.convex = setBorder.isSelected();
      owner.configUpdate();
    }
  }
  {
    squareDetector.contour2Poly_splitFraction = 0.1;
    squareDetector.contour2Poly_minimumSideFraction = 0.05;

    ConfigRefinePolygonLineToImage refineLine = new ConfigRefinePolygonLineToImage();
    refineLine.cornerOffset = 0;

    squareDetector.refine = refineLine;
  }
  {

    //		square.contour2Poly_splitFraction = 0.25;
    //		square.contour2Poly_minimumSplitFraction = 0.01;

    square.minimumEdgeIntensity = 0.1;

    square.minContourImageWidthFraction = 0.05;

    square.refineWithCorners = true;
    square.refineWithLines = false;

    // good value for squares.  Set it here to make it not coupled to default values
    square.configRefineCorners.cornerOffset = 1;
    square.configRefineCorners.lineSamples = 10;
    square.configRefineCorners.convergeTolPixels = 0.05;
    square.configRefineCorners.maxIterations = 10;

    // defaults for if the user toggles it to lines
    square.configRefineLines.cornerOffset = 1;
    square.configRefineLines.lineSamples = 10;
    square.configRefineLines.convergeTolPixels = 0.05;
    square.configRefineLines.maxIterations = 10;
  }
 private void updateSidesInConfig() {
   config.minimumSides = minSides;
   config.maximumSides = maxSides;
 }
  @Override
  public void stateChanged(ChangeEvent e) {
    PolygonRefineType refine = PolygonRefineType.values()[refineChoice.getSelectedIndex()];

    if (e.getSource() == spinnerMinEdge) {
      config.minimumEdgeIntensity = ((Number) spinnerMinEdge.getValue()).doubleValue();
    } else if (e.getSource() == spinnerMinSides) {
      minSides = ((Number) spinnerMinSides.getValue()).intValue();
      if (minSides > maxSides) {
        maxSides = minSides;
        spinnerMaxSides.setValue(minSides);
      }
      updateSidesInConfig();
    } else if (e.getSource() == spinnerMaxSides) {
      maxSides = ((Number) spinnerMaxSides.getValue()).intValue();
      if (maxSides < minSides) {
        minSides = maxSides;
        spinnerMinSides.setValue(minSides);
      }
      updateSidesInConfig();
    } else if (e.getSource() == selectZoom) {
      zoom = ((Number) selectZoom.getValue()).doubleValue();
      owner.viewUpdated();
      return;
    } else if (e.getSource() == spinnerMinContourSize) {
      config.minContourImageWidthFraction =
          ((Number) spinnerMinContourSize.getValue()).doubleValue();
    } else if (e.getSource() == spinnerContourSplit) {
      config.contour2Poly_splitFraction = ((Number) spinnerContourSplit.getValue()).doubleValue();
    } else if (e.getSource() == spinnerContourMinSplit) {
      config.contour2Poly_minimumSideFraction =
          ((Number) spinnerContourMinSplit.getValue()).doubleValue();
    } else if (e.getSource() == spinnerContourIterations) {
      config.contour2Poly_iterations = ((Number) spinnerContourIterations.getValue()).intValue();
    } else if (e.getSource() == spinnerSplitPenalty) {
      config.splitPenalty = ((Number) spinnerSplitPenalty.getValue()).doubleValue();
    } else if (e.getSource() == spinnerLineSamples) {
      if (refine == PolygonRefineType.LINE) {
        configLine.lineSamples = ((Number) spinnerLineSamples.getValue()).intValue();
      } else {
        configCorner.lineSamples = ((Number) spinnerLineSamples.getValue()).intValue();
      }
    } else if (e.getSource() == spinnerCornerOffset) {
      if (refine == PolygonRefineType.LINE) {
        configLine.cornerOffset = ((Number) spinnerCornerOffset.getValue()).intValue();
      } else {
        configCorner.cornerOffset = ((Number) spinnerCornerOffset.getValue()).intValue();
      }
    } else if (e.getSource() == spinnerSampleRadius) {
      if (refine == PolygonRefineType.LINE) {
        configLine.sampleRadius = ((Number) spinnerSampleRadius.getValue()).intValue();
      } else {
        configCorner.sampleRadius = ((Number) spinnerSampleRadius.getValue()).intValue();
      }
    } else if (e.getSource() == spinnerRefineMaxIterations) {
      if (refine == PolygonRefineType.LINE) {
        configLine.maxIterations = ((Number) spinnerRefineMaxIterations.getValue()).intValue();
      } else {
        configCorner.maxIterations = ((Number) spinnerRefineMaxIterations.getValue()).intValue();
      }
    } else if (e.getSource() == spinnerConvergeTol) {
      if (refine == PolygonRefineType.LINE) {
        configLine.convergeTolPixels = ((Number) spinnerConvergeTol.getValue()).doubleValue();
      } else {
        configCorner.convergeTolPixels = ((Number) spinnerConvergeTol.getValue()).doubleValue();
      }
    } else if (e.getSource() == spinnerMaxCornerChange) {
      if (refine == PolygonRefineType.LINE) {
        configLine.maxCornerChangePixel =
            ((Number) spinnerMaxCornerChange.getValue()).doubleValue();
      } else {
        configCorner.maxCornerChangePixel =
            ((Number) spinnerMaxCornerChange.getValue()).doubleValue();
      }
    }
    owner.configUpdate();
  }