1

Possible Duplicate:
Java - repaint(x, y, w, h) doesn't call paintComponent? (with SSCCE)

I'm trying out this neato performance trick repaint(x, y, w, h) and it sure is helping performance a lot.

Unfortunately, the special extras I've put into a paintComponent in the same class are now not being painted. I put a System.out.println() test at the beginning of paintComponent and it turns out it's not even called (as our astute readers probably were thinking from the beginning of this paragraph). When I use a plain repaint(), paintComponent() is called, no problem.

Specifically, I've got a JLabel, with a mouseListener, that on mouseEnter repaints the label.

What's the deal? I hope I'm missing something and this is still possible? That extra performance sure is nice...

Community
  • 1
  • 1
Ben
  • 54,723
  • 49
  • 178
  • 224
  • 1
    `... I hope I'm missing something... ` What you're missing is to add some code to your question so that we have half a prayer of being able to find your bug and help you. Best if you could create and post an [sscce](http://sscce.org). – Hovercraft Full Of Eels Feb 15 '12 at 02:52
  • http://stackoverflow.com/questions/9288127/java-repaintx-y-w-h-doesnt-call-paintcomponent-with-sscce – Ben Feb 15 '12 at 10:28

2 Answers2

2

repaint() is actually a one-liner that calls repaint(0, 0, width, height), so your basic thesis here -- that repaint() with arguments is fundamentally different from repaint() without -- is provably false. If I were a betting man, I'd bet that the arguments you're passing to this method describe a region with zero area (i.e., width <= 0) and so the RepaintManager is simply ignoring the requests.

You may be able to demonstrate this by changing the arguments to known good constant values, or maybe just println() the values of the arguments before you pass them.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • +1 for the help - thanks, that's exactly what I was looking for. Actually did print out and got nonzero values for x, y, w, and h. What I didn't get was an output in the actual paintComponent method...which leads me to my thesis :P – Ben Feb 15 '12 at 03:08
  • also - when I change the xy repaint to the plain repaint, the print in paintComponent does give an output. – Ben Feb 15 '12 at 03:10
  • also, again - what I'm mostly looking for is confirmation that "yes, the paintComponent method should be called under these circumstances" or "no, the dirty regions are assembled using paint" or something. – Ben Feb 15 '12 at 03:11
  • 1
    @Steve: there's no guarantee that paintComponent will be called for each call to the paint method, even if using the default method. The paint manager will queue the paint requests in the paint queue, but if the queue gets backed up, some painting will not be done. – Hovercraft Full Of Eels Feb 15 '12 at 03:22
  • @Hovercraft - interesting. So would this be one of those never-do-this situations where paint() could/should be overridden? – Ben Feb 15 '12 at 03:27
  • @Steve: the only never-do that I get out of this is that program logic should never be in the paintComponent method, and for 3 reasons: 1) you aren't guaranteed 100% that paintComponent will be called when you desire, 2) it can often be called at the suggestion of the OS and under no control from you, and 3) you want no code in paintComponent that is unrelated to painting and that could slow it down. For more on this, check out: [Painting in AWT and Swing](http://java.sun.com/products/jfc/tsc/articles/painting/) – Hovercraft Full Of Eels Feb 15 '12 at 03:35
  • I've read that a bunch of times :/ and there isn't any logic in paintComponent, just painting. The problem is, that painting isn't painting. Anyway I'll go hack it out myself with the tips here, at that point can SSCCE. – Ben Feb 15 '12 at 03:39
1

you can use JComponent#paintImmediately

1) be sure by testing your output to the Swing GUI by using / wrapping to the

if (SwingUtilities.isEventDispatchThread()) {

otherwise you could get an exception from RepaintManager

2) repaint() could be invoke EDT by default, untill first Thread#sleep(int) called

3) invoke code for painting from Swing Timer and output will be on EDT, but Timer doesn't works too if Thread#sleep(int) called

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Thanks mKorbel but actually solved in a duplicate question. Mods haven't granted my request to delete this question yet. Have a +1 for the trouble though. :) – Ben Feb 15 '12 at 09:49