public void paintComponent ( Graphics g ) { int WindowWidth = getSize ( ) . width ; int WindowHeight = getSize ( ) . height ; Tools . log ( "paintComponent called" ) ; if ( Dragging == false ) { //otherwise it's already a move Cursor setCursor ( new Cursor ( Cursor . WAIT_CURSOR ) ) ; } if ( sclPic . getScaledPicture ( ) != null ) { Graphics2D g2d = ( Graphics2D ) g ; int X_Offset = ( int ) ( ( double ) ( WindowWidth / 2 ) - ( focusPoint . x * sclPic . getScaleFactor ( ) ) ) ; int Y_Offset = ( int ) ( ( double ) ( WindowHeight / 2 ) - ( focusPoint . y * sclPic . getScaleFactor ( ) ) ) ; // clear damaged component area Rectangle clipBounds = g2d . getClipBounds ( ) ; g2d . setColor ( Color . black ) ; // getBackground()); g2d . fillRect ( clipBounds . x , clipBounds . y , clipBounds . width , clipBounds . height ) ; g2d . drawRenderedImage ( sclPic . getScaledPicture ( ) , AffineTransform . getTranslateInstance ( X_Offset , Y_Offset ) ) ; //g2d.drawImage(sclPic.getScaledPicture(), null, 0, 0); if ( showInfo ) { g2d . setColor ( Color . white ) ; g2d . drawString ( legend , infoPoint . x , infoPoint . y ) ; g2d . drawString ( "Size: " + Integer . toString ( sclPic . getOriginalWidth ( ) ) + " x " + Integer . toString ( sclPic . getOriginalHeight ( ) ) + " Offset: " + X_Offset + " x " + Y_Offset + " Mid: " + Integer . toString ( focusPoint . x ) + " x " + Integer . toString ( focusPoint . y ) + " Scale: " + twoDecimalFormatter . format ( sclPic . getScaleFactor ( ) ) , infoPoint . x , infoPoint . y + lineSpacing ) ; /* g2d.drawString("File: " + sclPic.getFilename() , infoPoint.x , infoPoint.y + (2 * lineSpacing) ); g2d.drawString("Loaded in: " + twoDecimalFormatter.format( sclPic.getSourcePicture().loadTime / 1000F ) + " Seconds" , infoPoint.x , infoPoint.y + (3 * lineSpacing) ); g2d.drawString("Free memory: " + Long.toString( Runtime.getRuntime().freeMemory( )/1024/1024, 0 ) + " MB" , infoPoint.x , infoPoint.y + (4 * lineSpacing) ); */ } } else { // paint a black square g . setClip ( 0 , 0 , WindowWidth , WindowHeight ) ; g . setColor ( Color . black ) ; g . fillRect ( 0 , 0 , WindowWidth , WindowHeight ) ; } if ( Dragging == false ) { //otherwise a move Cursor and should remain setCursor ( new Cursor ( Cursor . DEFAULT_CURSOR ) ) ; } }
we are overriding the default paintComponent method grabbing the Graphics handle and doing our own drawing here . Esentially this method draws a large black rectangle . A drawRenderedImage is then painted doing an affine transformation on the scaled image to position it so the the desired point is in the middle of the Graphics object . The picture is not scaled here because this is a slow operation and only needs to be done once while moving the image is something the user is likely to do more often .