• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

JPanel PaintComponent method gives OutOfMemoryError

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi
I need to display several images on a JPanel, effectively to make a kind of photo gallery. They are generally large jpg files (approx 1mb each), and I'm using the drawImage method of Graphics object to scale them down and draw them to the panel.

At the moment, I've got a JPanel, and have overridden the paintComponent(Graphics g) method to include a for loop which calls g.drawImage() for each element in an array of Image objects.

With 2 or 3 images it works well. However if I increase the number of images in the array to 6 or 7, I tend to get java.lang.OutOfMemoryErrors and it fails to paint all the images.

The paintComponent method is being called several hundred times while trying to paint the images.

Is there a more efficient and reliable way to be able to do this?

I've included the paintComponent method I'm using.

public void paintComponent(Graphics g){
super.paintComponent(g);
this.setOpaque(true);
int lastX = -10;
for(int i=0; i<images.length; i++){
Image img = images[i];
int imageWidth = img.getWidth(this);
int imageHeight = img.getHeight(this);

double scale = imageHeight/60;
g.drawImage(img, lastX+10, 0, (int)(lastX+10+(imageWidth/scale)), (int)(imageHeight/scale), 0, 0, imageWidth, imageHeight, this);
lastX += 10 + (imageWidth/scale);
}
}

Thanks.
 
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
one way..

You can extend the virtual memory while runing the UI.

for eg:
In command prompt

..>java -Xmx256m <class name>

------------------------------
Shanmugam
 
Ranch Hand
Posts: 1535
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Depending on the version of java you want to use, possibly. Since you are using the Image class and the scaling looks to be constant you might consider scaling the images as or soon after you load them. The Image method 'getScaledInstance' loads asynchronously so it works better with/needs a MediaTracker which you may already be using for the loading.

The call to 'setOpaque' should be located in the class constructor; we only need to call it one time.

If you can tolerate loading the images as BufferedImages you can take advantage of software acceleration. Use 'ImageIO.read' to load and AffineTransform to scale them on the fly. One potential drawback with this kind of on–the–fly scaling is a hardware acceleration–related bug in later j2se 1.4 – 1.5 versions that causes jerky movement in a JScrollPane.

You could use the same approach to create scaled images after loading the originals

and draw them with
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic