Hello,

I currently have this code to buffer an image:

public void paintComponent(Graphics g){
	Graphics2D g2 = (Graphics2D) g;
	ImageIcon icon = new ImageIcon("back.gif");
    Image image = icon.getImage();
    BufferedImage buff = new BufferedImage(image.getWidth(this), image.getHeight(this), BufferedImage.TYPE_INT_ARGB);
    Graphics2D b = (Graphics2D) buff.createGraphics();
    b.drawImage(image,imgX,imgY,this);		
	b.setColor(Color.BLUE);
	b.fillRect((window.getWidth()/2)-13, (window.getHeight()/2)-13, 26, 26);
	g2.drawImage(buff, 0, 0, this);
}

What it (should) do is load a background image. The background moves as I press the arrow keys (changing the imgX and imgY variables). The back.gif image is 5000 pixels square.

The issue is that when I don't buffer it flickers, when I use the above code, it takes FOREVER to move.

I know that 5000 pixel image isn't the best way to do this. And I think I'm on the right track when I say I need to crop it.

I would prefer to crop it in Java, although the code I find simply does not work. It either doesn't crop or doesn't show.

For reference: My JFrame is 1000x800.

Any advice/code is appreciated!

--Turt2Live

Dani AI

Generated

Nice follow-up to ’s hint — since reported that moving the expensive work out of the paint path fixed the immediate problem, here are concrete, practical steps to get smooth, flicker‑free panning without allocating on each frame.

/* load once (e.g. in ctor) */
BufferedImage background = ImageIO.read(new File("back.gif"));

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    int vw = getWidth();
    int vh = getHeight();

    int sx = Math.max(0, Math.min(background.getWidth() - vw, imgX));
    int sy = Math.max(0, Math.min(background.getHeight() - vh, imgY));

    // draw only the visible rectangle (no extra BufferedImage allocations)
    g.drawImage(background, 0, 0, vw, vh, sx, sy, sx + vw, sy + vh, null);

    // draw HUD/overlay
    g.setColor(Color.BLUE);
    g.fillRect((vw/2)-13, (vh/2)-13, 26, 26);
}

Practical notes and troubleshooting:

  • Call super.paintComponent(g) and ensure the component is opaque to avoid flicker.
  • Clamp imgX/imgY so source coords never go outside the large image (prevents exceptions and extra clipping work).
  • drawImage(..., sx, sy, sx+w, sy+h, ...) is usually faster than creating a subimage each frame; getSubimage(...) is cheap (it shares the raster) but still creates objects you might prefer to avoid.
  • If performance still lags, try GraphicsConfiguration.createCompatibleImage(...) or a VolatileImage for hardware acceleration, or tile the big image and load/render only visible tiles.
  • Keep object creation out of the paint path (no new BufferedImage, ImageIcon, etc. inside paintComponent), and repaint only when the view offset changes.

These steps provide a simple, low‑allocation panner for a very large background while keeping the UI responsive.

Recommended Answers

All 2 Replies

You re-load the image from file every time you draw it. That's wh yit's slow.
Read the file and create the buffered image once, at startup.

Thank You very much!

It worked :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.