/**
   * Method to check if the given x and y are in the picture
   *
   * @param column the horizontal value
   * @param row the vertical value
   * @return true if the row and column are in the picture and false otherwise
   */
  private boolean isLocationInPicture(int column, int row) {
    boolean result = false; // the default is false
    if (column >= 0 && column < picture.getWidth() && row >= 0 && row < picture.getHeight())
      result = true;

    return result;
  }
  /**
   * Zooms in the on picture by scaling the image. It is extremely memory intensive.
   *
   * @param factor the amount to zoom by
   */
  public void zoom(double factor) {
    // save the current zoom factor
    zoomFactor = factor;

    // calculate the new width and height and get an image that size
    int width = (int) (picture.getWidth() * zoomFactor);
    int height = (int) (picture.getHeight() * zoomFactor);
    BufferedImage bimg = picture.getBufferedImage();

    // set the scroll image icon to the new image
    imageDisplay.setImage(bimg.getScaledInstance(width, height, Image.SCALE_DEFAULT));
    imageDisplay.setCurrentX((int) (colIndex * zoomFactor));
    imageDisplay.setCurrentY((int) (rowIndex * zoomFactor));
    imageDisplay.revalidate();
    checkScroll(); // check if need to reposition scroll
  }
 /** Method to create and initialize the picture frame */
 private void createAndInitPictureFrame() {
   pictureFrame = new JFrame(); // create the JFrame
   pictureFrame.setResizable(true); // allow the user to resize it
   pictureFrame.getContentPane().setLayout(new BorderLayout()); // use border layout
   pictureFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // when close stop
   pictureFrame.setTitle(picture.getTitle());
   PictureExplorerFocusTraversalPolicy newPolicy = new PictureExplorerFocusTraversalPolicy();
   pictureFrame.setFocusTraversalPolicy(newPolicy);
 }
  /** Create and initialize the scrolling image */
  private void createAndInitScrollingImage() {
    scrollPane = new JScrollPane();

    BufferedImage bimg = picture.getBufferedImage();
    imageDisplay = new ImageDisplay(bimg);
    imageDisplay.addMouseMotionListener(this);
    imageDisplay.addMouseListener(this);
    imageDisplay.setToolTipText("Click a mouse button on a pixel to see the pixel information");
    scrollPane.setViewportView(imageDisplay);
    pictureFrame.getContentPane().add(scrollPane, BorderLayout.CENTER);
  }
  /**
   * Method to check that the current position is in the viewing area and if not scroll to center
   * the current position if possible
   */
  public void checkScroll() {
    // get the x and y position in pixels
    int xPos = (int) (colIndex * zoomFactor);
    int yPos = (int) (rowIndex * zoomFactor);

    // only do this if the image is larger than normal
    if (zoomFactor > 1) {

      // get the rectangle that defines the current view
      JViewport viewport = scrollPane.getViewport();
      Rectangle rect = viewport.getViewRect();
      int rectMinX = (int) rect.getX();
      int rectWidth = (int) rect.getWidth();
      int rectMaxX = rectMinX + rectWidth - 1;
      int rectMinY = (int) rect.getY();
      int rectHeight = (int) rect.getHeight();
      int rectMaxY = rectMinY + rectHeight - 1;

      // get the maximum possible x and y index
      int macolIndexX = (int) (picture.getWidth() * zoomFactor) - rectWidth - 1;
      int macolIndexY = (int) (picture.getHeight() * zoomFactor) - rectHeight - 1;

      // calculate how to position the current position in the middle of the viewing
      // area
      int viewX = xPos - (int) (rectWidth / 2);
      int viewY = yPos - (int) (rectHeight / 2);

      // reposition the viewX and viewY if outside allowed values
      if (viewX < 0) viewX = 0;
      else if (viewX > macolIndexX) viewX = macolIndexX;
      if (viewY < 0) viewY = 0;
      else if (viewY > macolIndexY) viewY = macolIndexY;

      // move the viewport upper left point
      viewport.scrollRectToVisible(new Rectangle(viewX, viewY, rectWidth, rectHeight));
    }
  }