/*
* GeoTools - OpenSource mapping toolkit
* http://geotools.org
* (C) 2007, GeoTools Project Managment Committee (PMC)
*
* 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;
* version 2.1 of the License.
*
* 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.
*/
package org.geotools.renderedimage.viewer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.RenderedImage;
import javax.swing.JPanel;
/**
* Simple viwer for rendered images, allows for zoom in/out, tile grid display
*
* @author Andrea Aime
*
*/
class ZoomableImageDisplay extends JPanel {
/** The image to display. */
protected RenderedImage image = null;
protected double scale = 1.0;
protected boolean tileGridVisible = true;
/**
* Constructs a <code>DisplayJAI</code> and sets its the layout to
* <code>null</code>.
*/
public ZoomableImageDisplay() {
super();
setLayout(null);
}
/**
* Constructs a <code>DisplayJAI</code>, sets its layout to
* <code>null</code>, and sets its displayed image.
*
* <p>
* The preferred size is set such that its width is the image width plus the
* left and right insets and its height is the image height plus the top and
* bottom insets.
* </p>
*
* @param image
* The image to display.
* @throws IllegalArgumentException
* if <code>image</code> is <code>null</code>.
*/
public ZoomableImageDisplay(RenderedImage image) {
this();
setImage(image);
}
public void setScale(double scale) {
if (scale <= 0)
throw new IllegalArgumentException("Scale must be a positive number");
this.scale = scale;
refreshComponent();
}
public double getScale() {
return scale;
}
/**
* Sets a new image to display.
*
* @param image
* The image to display.
* @throws IllegalArgumentException
* if <code>im</code> is <code>null</code>.
*/
public void setImage(RenderedImage image) {
if (image == null) {
throw new IllegalArgumentException("Image displayed cannot be null");
}
this.image = image;
refreshComponent();
}
public RenderedImage getImage() {
return image;
}
private void refreshComponent() {
int w = (int) Math.ceil(image.getWidth() * scale);
int h = (int) Math.ceil(image.getHeight() * scale);
int minX = (int) Math.ceil(image.getMinX() * scale);
int minY = (int) Math.ceil(image.getMinY() * scale);
Insets insets = getInsets();
Dimension dim = new Dimension(w + insets.left + insets.right + minX, h
+ insets.top + insets.bottom + minY);
setPreferredSize(dim);
revalidate();
repaint();
}
@Override
public synchronized void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
// clear damaged area
Rectangle clipBounds = g2d.getClipBounds();
g2d.setColor(getBackground());
g2d.fillRect(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
if (image == null)
return;
// Translation moves the entire image within the container
try {
g2d.drawRenderedImage(image, AffineTransform.getScaleInstance(scale, scale));
} catch (Throwable e) {
e.printStackTrace();
}
if (tileGridVisible) {
g2d.setColor(Color.WHITE);
g2d.setXORMode(Color.BLACK);
// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP));
final int x = (int) Math.floor(image.getTileGridXOffset() * scale);
final int y = (int) Math.floor(image.getTileGridYOffset() * scale);
final int th = (int) Math.round(image.getTileHeight() * scale);
final int tw = (int) Math.round(image.getTileWidth() * scale);
final int xCount = image.getNumXTiles();
final int yCount = image.getNumYTiles();
final int minty = image.getMinTileY();
final int mintx = image.getMinTileX();
for (int i = mintx; i < xCount + mintx + 1; i++) {
g2d.drawLine(x + tw * i, y + th * minty, x + tw * i, y + th * (yCount + minty));
}
for (int j = minty; j < yCount + minty + 1; j++) {
g2d.drawLine(x + mintx * tw, y + th * j, x + tw * (xCount + mintx), y + th * j);
}
}
}
public boolean isTileGridVisible() {
return tileGridVisible;
}
public void setTileGridVisible(boolean visible) {
this.tileGridVisible = visible;
repaint();
}
}