ui/src/main/java/ucar/nc2/ui/image/PicturePane.java
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)); 
		}
	}
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.