• 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 paint component called many times

 
Ranch Hand
Posts: 502
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am displaying a JPG on a JPanel. My code is
<blockquote>code:
<pre name="code" class="core">
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
// My code
}
</pre>
</blockquote>
The display is somewhat slow and I noticed in the debugger that paintComponent is called many times. I would like to know if there is any way to reduce the number of times that paintComponent is called.

Thanks in advance,

Alejandro Barrero
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No there isn't. Every time the panel needs to be painted, it will be painted. That is with each call to repaint() (which you may be able to control in your own code), but also whenever a component is added to the panel, the panel is made visible, the panel is resized, or even the window with the panel becomes the active window while the panel is shown.

Instead of asking how you can reduce the number of calls to this method, you should instead investigate what is making the repainting so slow? I've created a panel that, along with dozens of labels, can draw connectors between them, including arrow points that require multiple sine and cosine calculations. In the user interface itself you hardly know that anything is happening.
 
Alejandro Barrero
Ranch Hand
Posts: 502
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Rob. I am afraid I didn't explained correctly. Every time I execute repaint(), the paintComponent method is called many times. My jPanel is not part of an interface with buttons, labels or other components. I use it to display the contents of a JPG file; that is the reason that painting is slow and i don't see any way to make it faster. On the other hand, I am using repaint when I change the contents of the graphics and after considering your suggestion for a speedup I am beginning to think that I can use paintImmediately with the square that i need to repaint.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How do you paint your images? Do you load them in your paintComponent method from file? If so, it's wiser to just cache it and only change it when you want to display a different file.
 
Alejandro Barrero
Ranch Hand
Posts: 502
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I paint the image on the graphics of the JPane.
<blockquote>code:
<pre name="code" class="core">
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
if (this.bufferedImage == null) return;
int width = getWidth();
int height = getHeight();
Image scaledImage = this.bufferedImage.getScaledInstance(width, height,
BufferedImage.SCALE_DEFAULT);
Insets insets = getInsets();
graphics.drawImage(scaledImage, insets.left, insets.top, null);
graphics.setColor(Color.RED);
this.drawingFont = new Font("Hello, world", Font.BOLD, this.fontSize);
graphics.setFont(this.drawingFont);
// Draw all previously entered strings.
int numberOfStrings = this.enteredStrings.size();
for (int i = 0; i < numberOfStrings; i++) {
EnteredString nextEnteredString = this.enteredStrings.get(i);
String enteredText = nextEnteredString.getText();
int xCoordinate = nextEnteredString.getXCoordinate();
int yCoordinate = nextEnteredString.getYCoordinate();
graphics.drawString(enteredText, xCoordinate, yCoordinate);
}
// Draw all stamps.
int numberOfStamps = this.stamps.size();
for (int i = 0; i < numberOfStamps; i++) {
Signature signature = this.stamps.get(i);
drawSignature(signature);
}
}
</pre>
</blockquote>
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I think this is the culprit. Scaling images can take quite some time - I have had the same problem once.

Instead of scaling each time the panel is painted, try caching the scaled image as well and only scale when the panel is resized. You can use a ComponentListener to find out when a component is resized.

You will still get the problem when resizing the panel (or window) but at least it will be less frequent.

I'm also moving this thread to the Swing / AWT forum since it's really GUI related.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic