1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
/*
* ImageCanvas
*
* Copyright (c) 2000, 2001, 2002, 2003 Marco Schmidt.
* All rights reserved.
*/
package net.sourceforge.jiu.gui.awt;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
//import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
//import java.awt.RenderingHints;
import java.awt.ScrollPane;
import net.sourceforge.jiu.apps.EditorState;
/**
* An AWT canvas that displays an {@link java.awt.Image} object.
* Capable to display at arbitrary zooming levels.
* Does not use rendering hints because they require Java 1.2 or higher
* (although bilinear and bicubic interpolation usually improve display quality
* when zooming at the cost of slowing down image drawing).
*
* @author Marco Schmidt
*/
public class ImageCanvas extends Canvas
{
private Image image;
private int width;
private int height;
private int scaledWidth;
private int scaledHeight;
private double zoomFactorX = 1.0;
private double zoomFactorY = 1.0;
private boolean zoomToFit;
private ScrollPane myScrollPane;
public ImageCanvas(ScrollPane scrollPane)
{
myScrollPane = scrollPane;
//interpolation = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
}
public void computeZoomToFitSize()
{
if (!zoomToFit || myScrollPane == null)
{
return;
}
Dimension scrollPaneSize = myScrollPane.getSize();
int maxWidth = scrollPaneSize.width;
int maxHeight = scrollPaneSize.height;
double paneRatio = (double)maxWidth / (double)maxHeight;
double imageRatio = (double)width / (double)height;
if (paneRatio < imageRatio)
{
scaledWidth = maxWidth;
scaledHeight = (int)(scaledWidth * imageRatio);
}
else
{
scaledHeight = maxHeight;
scaledWidth = (int)(scaledHeight * imageRatio);
}
scaledHeight--;
scaledWidth--;
zoomFactorX = (double)scaledWidth / (double)width;
zoomFactorY = zoomFactorX;
}
public int getZoomPercentageX()
{
return (int)(zoomFactorX * 100.0);
}
public int getZoomPercentageY()
{
return (int)(zoomFactorY * 100.0);
}
public Dimension getPreferredSize()
{
return new Dimension(scaledWidth, scaledHeight);
}
/**
* Draws image to upper left corner.
*/
public void paint(Graphics g)
{
if (image == null)
{
super.paint(g);
}
else
{
Rectangle rect = getBounds();
int canvasWidth = rect.width;
int canvasHeight = rect.height;
int x1 = 0;
int y1 = 0;
if (canvasWidth > scaledWidth)
{
x1 = (canvasWidth - scaledWidth) / 2;
}
if (canvasHeight > scaledHeight)
{
y1 = (canvasHeight - scaledHeight) / 2;
}
if (canvasHeight > canvasWidth || canvasHeight > scaledHeight)
{
super.paint(g);
}
/* commented because Graphics2D requires Java 1.2+
if (g instanceof Graphics2D)
{
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolation);
}
*/
g.drawImage(image, x1, y1, scaledWidth, scaledHeight, this);
}
}
/**
* Specifies a new Image object to be displayed in this canvas.
* @param newImage the new Image object, potentially null
*/
public void setImage(Image newImage)
{
image = newImage;
width = image.getWidth(this);
height = image.getHeight(this);
scaledWidth = (int)(width * zoomFactorX);
scaledHeight = (int)(height * zoomFactorY);
/*zoomFactorX = 1.0;
zoomFactorY = 1.0;*/
setSize(scaledWidth, scaledHeight);
validate();
}
/**
* Sets both zoom factors to <code>1.0</code>.
*/
public void setOriginalSize()
{
setZoomFactor(1.0);
}
public double getZoomFactorX()
{
return zoomFactorX;
}
public double getZoomFactorY()
{
return zoomFactorY;
}
/**
* Sets the interpolation type used for drawing to the argument
* (must be one of the
* INTERPOLATION_xyz constants of EditorState), but does not
* do a redraw.
*/
public void setInterpolation(int newType)
{
switch(newType)
{
case(EditorState.INTERPOLATION_BICUBIC):
{
//interpolation = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
break;
}
case(EditorState.INTERPOLATION_BILINEAR):
{
//interpolation = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
break;
}
case(EditorState.INTERPOLATION_NEAREST_NEIGHBOR):
{
//interpolation = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
break;
}
}
}
public void setZoomFactor(double newZoomFactor)
{
setZoomFactors(newZoomFactor, newZoomFactor);
}
public void setZoomFactors(double newZoomFactorX, double newZoomFactorY)
{
if (newZoomFactorX <= 0.0 || newZoomFactorY <= 0.0)
{
throw new IllegalArgumentException("Zoom factors must be larger than 0.0.");
}
zoomFactorX = newZoomFactorX;
zoomFactorY = newZoomFactorY;
scaledWidth = (int)(width * zoomFactorX);
scaledHeight = (int)(height * zoomFactorY);
setSize(scaledWidth, scaledHeight);
myScrollPane.validate();
}
public void setZoomToFit(boolean newValue)
{
zoomToFit = newValue;
validate();
}
/**
* Simply calls {@link #paint(Graphics)} with the argument.
* @param g Graphics context
*/
public void update(Graphics g)
{
paint(g);
}
}
|