paintComponent looping numerous times

gavrile
gavrile used Ask the Experts™
on
Hi all, I want to display an Image on a panel and for that I used the method paintComponent. The problem is that this method loops hundreds of times each time I activate it. I've checked already the class that uses this panel's class and the fault is not there (it calls the paintComponent methods only once).


This is the class code:
import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;


public class FilePanel extends JPanel {
  protected Image currentImage;
  private boolean isFile = false;
  private final int fileWidth = 100, fileHeight = 60;
  private int count = 0;

  public FilePanel() {
    setBorder (BorderFactory.createTitledBorder("Picture Area:"));
  }


  public void setFile(String fileName) {
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    currentImage = toolkit.getImage(fileName);
    System.out.println(fileName);
    isFile = true;
    repaint();
  }

  public void refreshPanel ()
  {
    isFile = false;
    repaint();
  }

  public void paintComponent (Graphics graphics)
  {
    super.paintComponent(graphics);
    if (isFile)
    {
      graphics.drawImage(currentImage, (getWidth() - fileWidth)/2,
        0, fileWidth, fileHeight, this);
    }
  }
}

I'll be happy to hear any suggestions.
Thanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Hi,

I don't see a problem in your code. What's around your panel? For example, could you check container where you add your panel.

BTW, why don't you simply use JLabel with ImageIcon?

Regards,
Igor Bazarny

Author

Commented:
I've checked the container, and it does not cause multiple calls of paintCompoent.
I'm not using ImageIcon, because I want to control the size of the image.
If you have any other ideas I'll be happy to hear them.
Thanks, Gabi
Try to write

new Exception().printStackTrace() in your paintComponent() and investigate where it's called from
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

Author

Commented:
The printStackTrace() gives a notice about an error concerning: "EventQueue" and "EventDispatchThread". Does it tell you anything?

Author

Commented:
The printStackTrace() gives a notice about an error concerning: "EventQueue" and "EventDispatchThread". Does it tell you anything?

Author

Commented:
The printStackTrace() gives a notice about an error concerning: "EventQueue" and "EventDispatchThread". Does it tell you anything?
Mick BarryJava Developer
Top Expert 2010
Commented:
paintComponent() will get called multiple times.
More specifically, anytime a portion of your panel needs repainting, then paintComponent will be called to achieve this. This is normal behaviour.
Use ImageIcon, u can actually use it as an image if u want to control the size like,
g.drawImage(imageicon.getImage(),x,y,width,height,null);
Mick BarryJava Developer
Top Expert 2010

Commented:
All that does is use ImageIcon to load the image.
It won't change how often paintComponent() gets called.
Is stack trace aways the same? Could you post it here? EventQueue and EventDispatchThread will almost always appear in such stack trace.

object is right, paintComponent is always called multiple times when swing desides that it's time to repaint component. Any time your component is covered by another component then uncovered it needs to be repainted. Any time your component resized or moved it needs to be repainted. Any time foreground or background color changes, swing component will be repainted. There are other properties which trigger repaint when changed.

I don't believe that hundreds of times is a norm for paintComponent calls. But plain search for paintComponent() calls won't help you to find problem. I think that printing stack trace from the repaint method would help to find what triggers call to paintComponent()--typically component is not redrawn immediately on property change to decrease number of repaints when several properties change.

Regards,
Igor Bazarny

Author

Commented:
Hi Igor, and thank you all for your comments.
I'm sorry I couldn't get back to you yesterday.
The exception is always the same and it says:

at com.Gabi.FilePanel.paintComponent (Compiled Code)
at javax.swing.JComponent.paint (Compiled Code)
at javax.swing.JComponent.paintWithBuffer (Compiled Code)
at javax.swing.JComponent._paintImmediately (Compiled Code)
at javax.swing.JComponent.paintImmediately (Compiled Code)
at javax.swing.RepairManager.paintDirtyRegions (Compiled Code)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run (Compiled Code)


...and it goes on.
If you have any ideas or suggestions, please share them with me.
Thanks, Gabi
So, there is some reason it thinks that your component has dirty regions. It could be call to one of repaint() variants on your component. I would put trace to repaint and investigated where it's called from.

Regards,
Igor Bazarny  
Under 'trace' I meean new Exception().printStackTrace() construct
Mick BarryJava Developer
Top Expert 2010

Commented:
So if your window is sitting there doing nothing, how often/regularly is paintComponent() getting called?

Author

Commented:
Hello all, Igor I've put trace on the repaint and that's what I got.
objects I did not understand your question. When paintComponent is not called by me it is not active, but when I call it once, it performs a few hundred loops.
Thanks for your help, Gabi
Mick BarryJava Developer
Top Expert 2010

Commented:
> but when I call it once

You should never need to call paintComponent().
Why are you calling it?
Hi,

It was trace form the paintComponent(). It was initiated by swing, because some part of your component was marked as 'dirty'. Normal way to mark part of the component 'dirty' is call to repaint(), which is not the same as call to paint() or paintComponent(). I'd like to know why some part of your component was marked 'dirty'. I hope it will help us to understand why your paintComponent() is called so many times.

And objects is right, normally you don't need to call paintComponent().

Regards,
Igor Bazarny

Author

Commented:
Hi,
First of all, how can I check which part of my component is dirty, or why has it become dirty?
Second, I'm using paintComponent in order to display an Image (a gif file) on a panel. This is the most straightforward way I know, but I'm open to any suggestions.
Thanks, Gabi
Mick BarryJava Developer
Top Expert 2010

Commented:
Repeating, you do not need to call paintComponent. It will get called by the event dispatch thread as needed.
You can (and should) remove all calls to paintComponent().
Hi,

Gabi, I'm getting nervous. Do you understand that repaint() and paintComponent() are different methods? Regions are marked dirty by one if repaint() methods. Can you override repaint methods in following way:

public void repaint(<arg list>){
    super.repaint(<args>);
    new Exception("repaint("+<comma-separated args>+")").printStackTrace();
}

(for all variants of repaint) and see where repaint is called from? It will help us to understand why some region is marked dirty.

Regards,
Igor Bazarny
gavrile:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.

Commented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

- Split points between bazarny and objects

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Venabili
EE Cleanup Volunteer

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial