File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Swing / AWT / SWT and the fly likes JPanel paint component called many times Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "JPanel paint component called many times" Watch "JPanel paint component called many times" New topic
Author

JPanel paint component called many times

Alejandro Barrero
Ranch Hand

Joined: Aug 01, 2005
Posts: 309
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


Your help will be greatly appreciated,
Alejandro Barrero
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19655
    
  18

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.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Alejandro Barrero
Ranch Hand

Joined: Aug 01, 2005
Posts: 309
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

Joined: Oct 27, 2005
Posts: 19655
    
  18

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

Joined: Aug 01, 2005
Posts: 309
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

Joined: Oct 27, 2005
Posts: 19655
    
  18


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.
 
Consider Paul's rocket mass heater.
 
subject: JPanel paint component called many times
 
Similar Threads
NullPointerException with setCaretPosition?
Conditional (Ternary) Operator (?:)
Using SQL Server 2005 jdbc
How many threads are there?
StringBuffer / StringBuilder methods