/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2016 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.core.gui;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.Raster;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Map;
import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils;
import org.jfree.text.TextUtilities;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.SwingUniversalImage;
import org.pentaho.di.core.SwingUniversalImageBitmap;
import org.pentaho.di.core.SwingUniversalImageSvg;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.svg.SvgImage;
import org.pentaho.di.core.svg.SvgSupport;
import org.pentaho.di.core.util.SwingSvgImageUtil;
import org.pentaho.di.job.entry.JobEntryCopy;
import org.pentaho.di.laf.BasePropertyHandler;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.reporting.libraries.base.util.WaitingImageObserver;
public class SwingGC implements GCInterface {
private static SwingUniversalImage imageLocked;
private static SwingUniversalImage imageStepError;
private static SwingUniversalImage imageEdit;
private static SwingUniversalImage imageContextMenu;
private static SwingUniversalImage imageTrue;
private static SwingUniversalImage imageFalse;
private static SwingUniversalImage imageErrorHop;
private static SwingUniversalImage imageInfoHop;
private static SwingUniversalImage imageHopTarget;
private static SwingUniversalImage imageHopInput;
private static SwingUniversalImage imageHopOutput;
private static SwingUniversalImage imageArrow;
private static SwingUniversalImage imageCopyHop;
private static SwingUniversalImage imageLoadBalance;
private static SwingUniversalImage imageCheckpoint;
private static SwingUniversalImage imageDatabase;
private static SwingUniversalImage imageParallelHop;
private static SwingUniversalImage imageUnconditionalHop;
private static SwingUniversalImage imageStart;
private static SwingUniversalImage imageDummy;
private static SwingUniversalImage imageBusy;
private static SwingUniversalImage imageInject;
private static SwingUniversalImage defaultArrow;
private static SwingUniversalImage okArrow;
private static SwingUniversalImage errorArrow;
private static SwingUniversalImage disabledArrow;
protected Color background;
protected Color black;
protected Color red;
protected Color yellow;
protected Color orange;
protected Color green;
protected Color blue;
protected Color magenta;
protected Color gray;
protected Color lightGray;
protected Color darkGray;
protected Color lightBlue;
protected Color crystal;
protected Color hopDefault;
protected Color hopOK;
private Graphics2D gc;
private int iconsize;
//TODO should be changed to PropsUI usage
private int small_icon_size = 16;
private Map<String, SwingUniversalImage> stepImages;
private Map<String, SwingUniversalImage> entryImages;
private BufferedImage image;
private ImageObserver observer;
private Point area;
private int alpha;
private Font fontGraph;
private Font fontNote;
private Font fontSmall;
private int lineWidth;
private ELineStyle lineStyle;
private int yOffset;
private int xOffset;
private boolean drawingPixelatedImages;
private AffineTransform originalTransform;
private SwingGC( BufferedImage image, Graphics2D gc, ImageObserver observer,
Point area, int iconsize, int xOffset, int yOffset ) throws KettleException {
this.image = image;
this.gc = gc;
if ( gc == null && image != null ) {
this.gc = image.createGraphics();
}
this.observer = observer;
this.stepImages = SwingGUIResource.getInstance().getStepImages();
this.entryImages = SwingGUIResource.getInstance().getEntryImages();
this.iconsize = iconsize;
this.area = area;
this.xOffset = xOffset;
this.yOffset = yOffset;
this.originalTransform = this.gc.getTransform();
init();
}
public SwingGC( ImageObserver observer, Point area, int iconsize, int xOffset, int yOffset ) throws KettleException {
this( new BufferedImage( area.x, area.y, BufferedImage.TYPE_INT_ARGB ), null, observer,
area, iconsize, xOffset, yOffset );
}
public SwingGC( Graphics2D gc, Rectangle2D rect, int iconsize, int xOffset, int yOffset ) throws KettleException {
this( null, gc, null,
new Point( (int) rect.getWidth(), (int) rect.getHeight() ), iconsize, xOffset, yOffset );
}
private void init() throws KettleException {
this.lineStyle = ELineStyle.SOLID;
this.lineWidth = 1;
this.alpha = 255;
this.background = new Color( 255, 255, 255 );
this.black = new Color( 0, 0, 0 );
this.red = new Color( 255, 0, 0 );
this.yellow = new Color( 255, 255, 0 );
this.orange = new Color( 255, 165, 0 );
this.green = new Color( 0, 255, 0 );
this.blue = new Color( 0, 0, 255 );
this.magenta = new Color( 255, 0, 255 );
this.gray = new Color( 128, 128, 128 );
this.lightGray = new Color( 200, 200, 200 );
this.darkGray = new Color( 80, 80, 80 );
this.lightBlue = new Color( 135, 206, 250 ); // light sky blue
this.crystal = new Color( 61, 99, 128 );
this.hopDefault = new Color( 61, 99, 128 );
this.hopOK = new Color( 12, 178, 15 );
imageLocked = getImageIcon( BasePropertyHandler.getProperty( "Locked_image" ) );
imageStepError = getImageIcon( BasePropertyHandler.getProperty( "StepErrorLines_image" ) );
imageEdit = getImageIcon( BasePropertyHandler.getProperty( "EditSmall_image" ) );
imageContextMenu = getImageIcon( BasePropertyHandler.getProperty( "ContextMenu_image" ) );
imageTrue = getImageIcon( BasePropertyHandler.getProperty( "True_image" ) );
imageFalse = getImageIcon( BasePropertyHandler.getProperty( "False_image" ) );
imageErrorHop = getImageIcon( BasePropertyHandler.getProperty( "ErrorHop_image" ) );
imageInfoHop = getImageIcon( BasePropertyHandler.getProperty( "InfoHop_image" ) );
imageHopTarget = getImageIcon( BasePropertyHandler.getProperty( "HopTarget_image" ) );
imageHopInput = getImageIcon( BasePropertyHandler.getProperty( "HopInput_image" ) );
imageHopOutput = getImageIcon( BasePropertyHandler.getProperty( "HopOutput_image" ) );
imageArrow = getImageIcon( BasePropertyHandler.getProperty( "ArrowIcon_image" ) );
imageCopyHop = getImageIcon( BasePropertyHandler.getProperty( "CopyHop_image" ) );
imageLoadBalance = getImageIcon( BasePropertyHandler.getProperty( "LoadBalance_image" ) );
imageCheckpoint = getImageIcon( BasePropertyHandler.getProperty( "CheckeredFlag_image" ) );
imageDatabase = getImageIcon( BasePropertyHandler.getProperty( "Database_image" ) );
imageParallelHop = getImageIcon( BasePropertyHandler.getProperty( "ParallelHop_image" ) );
imageUnconditionalHop = getImageIcon( BasePropertyHandler.getProperty( "UnconditionalHop_image" ) );
imageStart = getImageIcon( BasePropertyHandler.getProperty( "STR_image" ) );
imageDummy = getImageIcon( BasePropertyHandler.getProperty( "DUM_image" ) );
imageBusy = getImageIcon( BasePropertyHandler.getProperty( "Busy_image" ) );
imageInject = getImageIcon( BasePropertyHandler.getProperty( "Inject_image" ) );
defaultArrow = getImageIcon( BasePropertyHandler.getProperty( "defaultArrow_image" ) );
okArrow = getImageIcon( BasePropertyHandler.getProperty( "okArrow_image" ) );
errorArrow = getImageIcon( BasePropertyHandler.getProperty( "errorArrow_image" ) );
disabledArrow = getImageIcon( BasePropertyHandler.getProperty( "disabledArrow_image" ) );
fontGraph = new Font( "FreeSans", Font.PLAIN, 10 );
fontNote = new Font( "FreeSans", Font.PLAIN, 10 );
fontSmall = new Font( "FreeSans", Font.PLAIN, 8 );
gc.setFont( fontGraph );
gc.setColor( background );
gc.fillRect( 0, 0, area.x, area.y );
}
private SwingUniversalImage getImageIcon( String fileName ) throws KettleException {
SwingUniversalImage image = null;
InputStream inputStream = null;
if ( fileName == null ) {
throw new KettleException( "Image icon file name can not be null" );
}
if ( SvgSupport.isSvgEnabled() && SvgSupport.isSvgName( fileName ) ) {
try {
inputStream = new FileInputStream( fileName );
} catch ( FileNotFoundException ex ) {
// no need to fail
}
if ( inputStream == null ) {
try {
inputStream = new FileInputStream( "/" + fileName );
} catch ( FileNotFoundException ex ) {
// no need to fail
}
}
if ( inputStream == null ) {
inputStream = getClass().getResourceAsStream( fileName );
}
if ( inputStream == null ) {
inputStream = getClass().getResourceAsStream( "/" + fileName );
}
if ( inputStream != null ) {
try {
SvgImage svg = SvgSupport.loadSvgImage( inputStream );
image = new SwingUniversalImageSvg( svg );
} catch ( Exception ex ) {
throw new KettleException( "Unable to load image from classpath : '" + fileName + "'", ex );
} finally {
IOUtils.closeQuietly( inputStream );
}
}
}
if ( image == null ) {
fileName = SvgSupport.toPngName( fileName );
try {
inputStream = new FileInputStream( fileName );
} catch ( FileNotFoundException ex ) {
// no need to fail
}
if ( inputStream == null ) {
try {
inputStream = new FileInputStream( "/" + fileName );
} catch ( FileNotFoundException ex ) {
// no need to fail
}
}
if ( inputStream == null ) {
inputStream = getClass().getResourceAsStream( fileName );
}
if ( inputStream == null ) {
inputStream = getClass().getResourceAsStream( "/" + fileName );
}
if ( inputStream != null ) {
try {
BufferedImage bitmap = ImageIO.read( inputStream );
WaitingImageObserver wia = new WaitingImageObserver( bitmap );
wia.waitImageLoaded();
image = new SwingUniversalImageBitmap( bitmap );
} catch ( Exception ex ) {
throw new KettleException( "Unable to load image from classpath : '" + fileName + "'", ex );
} finally {
IOUtils.closeQuietly( inputStream );
}
}
}
if ( image == null ) {
throw new KettleException( "Unable to load image from classpath : '" + fileName + "'" );
}
return image;
}
public void dispose() {
}
public void drawLine( int x, int y, int x2, int y2 ) {
gc.drawLine( x + xOffset, y + yOffset, x2 + xOffset, y2 + yOffset );
}
@Override
public void drawImage( String location, ClassLoader classLoader, int x, int y ) {
SwingUniversalImage img = SwingSvgImageUtil.getUniversalImage( classLoader, location );
drawImage( img, x, y, small_icon_size );
}
@Override
public void drawImage( EImage image, int x, int y ) {
drawImage( image, x, y, 0.0f );
}
@Override
public void drawImage( EImage image, int locationX, int locationY, float magnification ) {
SwingUniversalImage img = getNativeImage( image );
drawImage( img, locationX, locationY, small_icon_size );
// gc.drawImage(img, locationX+xOffset, locationY+yOffset, observer);
}
public void drawImage( EImage image, int x, int y, int width, int height, float magnification ) {
SwingUniversalImage img = getNativeImage( image );
drawImage( img, x, y, width, height );
}
@Override
public void drawImage( EImage image, int x, int y, float magnification, double angle ) {
SwingUniversalImage img = getNativeImage( image );
drawImage( img, x, y, angle, small_icon_size );
}
private void drawImage( SwingUniversalImage image, int locationX, int locationY, int imageSize ) {
if ( isDrawingPixelatedImages() && image.isBitmap() ) {
BufferedImage img = image.getAsBitmapForSize( imageSize, imageSize );
ColorModel cm = img.getColorModel();
Raster raster = img.getRaster();
for ( int x = 0; x < img.getWidth( observer ); x++ ) {
for ( int y = 0; y < img.getHeight( observer ); y++ ) {
Object pix = raster.getDataElements( x, y, null );
gc.setColor( new Color( cm.getRed( pix ), cm.getGreen( pix ), cm.getBlue( pix ), cm.getAlpha( pix ) ) );
gc.setStroke( new BasicStroke( 1.0f ) );
gc.drawLine(
locationX + xOffset + x,
locationY + yOffset + y,
locationX + xOffset + x + 1,
locationY + yOffset + y + 1 );
}
}
} else {
image.drawToGraphics( gc, locationX, locationY, imageSize, imageSize );
}
}
private void drawImage( SwingUniversalImage image, int centerX, int centerY, double angle, int imageSize ) {
if ( isDrawingPixelatedImages() && image.isBitmap() ) {
BufferedImage img = image.getAsBitmapForSize( imageSize, imageSize, angle );
ColorModel cm = img.getColorModel();
Raster raster = img.getRaster();
int offx = centerX + xOffset - img.getWidth() / 2;
int offy = centerY + yOffset - img.getHeight() / 2;
for ( int x = 0; x < img.getWidth( observer ); x++ ) {
for ( int y = 0; y < img.getHeight( observer ); y++ ) {
Object pix = raster.getDataElements( x, y, null );
gc.setColor( new Color( cm.getRed( pix ), cm.getGreen( pix ), cm.getBlue( pix ), cm.getAlpha( pix ) ) );
gc.setStroke( new BasicStroke( 1.0f ) );
gc.drawLine(
offx + x,
offy + y,
offx + x + 1,
offy + y + 1 );
}
}
} else {
image.drawToGraphics( gc, centerX, centerY, imageSize, imageSize, angle );
}
}
public Point getImageBounds( EImage image ) {
return new Point( small_icon_size, small_icon_size );
}
public static final SwingUniversalImage getNativeImage( EImage image ) {
switch ( image ) {
case LOCK:
return imageLocked;
case STEP_ERROR:
return imageStepError;
case EDIT:
return imageEdit;
case CONTEXT_MENU:
return imageContextMenu;
case TRUE:
return imageTrue;
case FALSE:
return imageFalse;
case ERROR:
return imageErrorHop;
case INFO:
return imageInfoHop;
case TARGET:
return imageHopTarget;
case INPUT:
return imageHopInput;
case OUTPUT:
return imageHopOutput;
case ARROW:
return imageArrow;
case COPY_ROWS:
return imageCopyHop;
case LOAD_BALANCE:
return imageLoadBalance;
case CHECKPOINT:
return imageCheckpoint;
case DB:
return imageDatabase;
case PARALLEL:
return imageParallelHop;
case UNCONDITIONAL:
return imageUnconditionalHop;
case BUSY:
return imageBusy;
case INJECT:
return imageInject;
case ARROW_DEFAULT:
return defaultArrow;
case ARROW_OK:
return okArrow;
case ARROW_ERROR:
return errorArrow;
case ARROW_DISABLED:
return disabledArrow;
default:
break;
}
return null;
}
public void drawPoint( int x, int y ) {
gc.drawLine( x + xOffset, y + yOffset, x + xOffset, y + yOffset );
}
public void drawPolygon( int[] polygon ) {
gc.drawPolygon( getSwingPolygon( polygon ) );
}
private Polygon getSwingPolygon( int[] polygon ) {
int nPoints = polygon.length / 2;
int[] xPoints = new int[polygon.length / 2];
int[] yPoints = new int[polygon.length / 2];
for ( int i = 0; i < nPoints; i++ ) {
xPoints[i] = polygon[2 * i + 0] + xOffset;
yPoints[i] = polygon[2 * i + 1] + yOffset;
}
return new Polygon( xPoints, yPoints, nPoints );
}
public void drawPolyline( int[] polyline ) {
int nPoints = polyline.length / 2;
int[] xPoints = new int[polyline.length / 2];
int[] yPoints = new int[polyline.length / 2];
for ( int i = 0; i < nPoints; i++ ) {
xPoints[i] = polyline[2 * i + 0] + xOffset;
yPoints[i] = polyline[2 * i + 1] + yOffset;
}
gc.drawPolyline( xPoints, yPoints, nPoints );
}
public void drawRectangle( int x, int y, int width, int height ) {
gc.drawRect( x + xOffset, y + yOffset, width, height );
}
public void drawRoundRectangle( int x, int y, int width, int height, int circleWidth, int circleHeight ) {
gc.drawRoundRect( x + xOffset, y + yOffset, width, height, circleWidth, circleHeight );
}
public void drawText( String text, int x, int y ) {
int height = gc.getFontMetrics().getHeight();
String[] lines = text.split( "\n" );
for ( String line : lines ) {
gc.drawString( line, x + xOffset, y + height + yOffset );
y += height;
}
}
public void drawText( String text, int x, int y, boolean transparent ) {
drawText( text, x, y );
}
public void fillPolygon( int[] polygon ) {
switchForegroundBackgroundColors();
gc.fillPolygon( getSwingPolygon( polygon ) );
switchForegroundBackgroundColors();
}
public void fillRectangle( int x, int y, int width, int height ) {
switchForegroundBackgroundColors();
gc.fillRect( x + xOffset, y + yOffset, width, height );
switchForegroundBackgroundColors();
}
// TODO: complete code
public void fillGradientRectangle( int x, int y, int width, int height, boolean vertical ) {
fillRectangle( x, y, width, height );
}
public void fillRoundRectangle( int x, int y, int width, int height, int circleWidth, int circleHeight ) {
switchForegroundBackgroundColors();
gc.fillRoundRect( x + xOffset, y + yOffset, width, height, circleWidth, circleHeight );
switchForegroundBackgroundColors();
}
public Point getDeviceBounds() {
return area;
}
public void setAlpha( int alpha ) {
this.alpha = alpha;
AlphaComposite alphaComposite = AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha / 255 );
gc.setComposite( alphaComposite );
}
public int getAlpha() {
return alpha;
}
public void setBackground( EColor color ) {
gc.setBackground( getColor( color ) );
}
private Color getColor( EColor color ) {
switch ( color ) {
case BACKGROUND:
return background;
case BLACK:
return black;
case RED:
return red;
case YELLOW:
return yellow;
case ORANGE:
return orange;
case GREEN:
return green;
case BLUE:
return blue;
case MAGENTA:
return magenta;
case GRAY:
return gray;
case LIGHTGRAY:
return lightGray;
case DARKGRAY:
return darkGray;
case LIGHTBLUE:
return lightBlue;
case CRYSTAL:
return crystal;
case HOP_DEFAULT:
return hopDefault;
case HOP_OK:
return hopOK;
default:
break;
}
return null;
}
public void setFont( EFont font ) {
switch ( font ) {
case GRAPH:
gc.setFont( fontGraph );
break;
case NOTE:
gc.setFont( fontNote );
break;
case SMALL:
gc.setFont( fontSmall );
break;
default:
break;
}
}
public void setForeground( EColor color ) {
gc.setColor( getColor( color ) );
}
public void setLineStyle( ELineStyle lineStyle ) {
this.lineStyle = lineStyle;
gc.setStroke( createStroke() );
}
private Stroke createStroke() {
float[] dash;
switch ( lineStyle ) {
case SOLID:
dash = null;
break;
case DOT:
dash = new float[] { 5, };
break;
case DASHDOT:
dash = new float[] { 10, 5, 5, 5, };
break;
case PARALLEL:
dash = new float[] { 10, 5, 10, 5, };
break;
case DASH:
dash = new float[] { 6, 2, };
break;
default:
throw new RuntimeException( "Unhandled line style!" );
}
return new BasicStroke( lineWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 2, dash, 0 );
}
public void setLineWidth( int width ) {
this.lineWidth = width;
gc.setStroke( createStroke() );
}
public void setTransform( float translationX, float translationY, int shadowsize, float magnification ) {
// PDI-9953 - always use original GC's transform.
AffineTransform transform = (AffineTransform) originalTransform.clone();
transform.translate( translationX + shadowsize * magnification, translationY + shadowsize * magnification );
transform.scale( magnification, magnification );
gc.setTransform( transform );
}
public AffineTransform getTransform() {
return gc.getTransform();
}
public Point textExtent( String text ) {
String[] lines = text.split( Const.CR );
int maxWidth = 0;
for ( String line : lines ) {
Rectangle2D bounds = TextUtilities.getTextBounds( line, gc, gc.getFontMetrics() );
if ( bounds.getWidth() > maxWidth ) {
maxWidth = (int) bounds.getWidth();
}
}
int height = gc.getFontMetrics().getHeight() * lines.length;
return new Point( maxWidth, height );
}
public void drawStepIcon( int x, int y, StepMeta stepMeta, float magnification ) {
String steptype = stepMeta.getStepID();
SwingUniversalImage im = stepImages.get( steptype );
if ( im != null ) { // Draw the icon!
drawImage( im, x + xOffset, y + xOffset, iconsize );
}
}
public void drawJobEntryIcon( int x, int y, JobEntryCopy jobEntryCopy, float magnification ) {
if ( jobEntryCopy == null ) {
return; // Don't draw anything
}
SwingUniversalImage image = null;
if ( jobEntryCopy.isSpecial() ) {
if ( jobEntryCopy.isStart() ) {
image = imageStart;
}
if ( jobEntryCopy.isDummy() ) {
image = imageDummy;
}
} else {
String configId = jobEntryCopy.getEntry().getPluginId();
if ( configId != null ) {
image = entryImages.get( configId );
}
}
if ( image == null ) {
return;
}
drawImage( image, x + xOffset, y + xOffset, iconsize );
// gc.drawImage(image, x+xOffset, y+yOffset, observer);
}
@Override
public void drawJobEntryIcon( int x, int y, JobEntryCopy jobEntryCopy ) {
drawJobEntryIcon( x, y, jobEntryCopy, 1.0f );
}
@Override
public void drawStepIcon( int x, int y, StepMeta stepMeta ) {
drawStepIcon( x, y, stepMeta, 1.0f );
}
public void setAntialias( boolean antiAlias ) {
if ( antiAlias ) {
RenderingHints hints =
new RenderingHints( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
hints.add( new RenderingHints( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY ) );
hints.add( new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ) );
// hints.add(new RenderingHints(RenderingHints.KEY_ALPHA_INTERPOLATION,
// RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY));
gc.setRenderingHints( hints );
}
}
public void setBackground( int r, int g, int b ) {
Color color = getColor( r, g, b );
gc.setBackground( color );
}
public void setForeground( int r, int g, int b ) {
Color color = getColor( r, g, b );
gc.setColor( color );
}
private Color getColor( int r, int g, int b ) {
return new Color( r, g, b );
}
public void setFont( String fontName, int fontSize, boolean fontBold, boolean fontItalic ) {
int style = Font.PLAIN;
if ( fontBold ) {
style = Font.BOLD;
}
if ( fontItalic ) {
style = style | Font.ITALIC;
}
Font font = new Font( fontName, style, fontSize );
gc.setFont( font );
}
public Object getImage() {
return image;
}
public void switchForegroundBackgroundColors() {
Color fg = gc.getColor();
Color bg = gc.getBackground();
gc.setColor( bg );
gc.setBackground( fg );
}
public Point getArea() {
return area;
}
/**
* @return the drawingPixelatedImages
*/
public boolean isDrawingPixelatedImages() {
return drawingPixelatedImages;
}
/**
* @param drawingPixelatedImages
* the drawingPixelatedImages to set
*/
public void setDrawingPixelatedImages( boolean drawingPixelatedImages ) {
this.drawingPixelatedImages = drawingPixelatedImages;
}
@Override
public void drawImage( BufferedImage image, int x, int y ) {
gc.drawImage( image, x, y, observer );
}
}