2

How to know that paintComponent(Graphics g) has finished it's job?

I can do:

 @Override
 public void paintComponent(Graphics g) {
    try {
         //Paint some stuff
    } finally {
         //Do something after painting
    }
 }

Is there any other way?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Ernestas Gruodis
  • 8,567
  • 14
  • 55
  • 117
  • 3
    This seems like a strange request to me, and leads me to ask: What are you trying to do after painting? Hopefully no program logic will go inside of that method, but my fear is that you have in fact done just this. And why show the `paint(...)` but talk about the `paintComponent(...)` method? – Hovercraft Full Of Eels Sep 05 '13 at 12:37
  • You can override `paintComponent()` and call `super.paintComponent()`, after which that call is obviously finished, but I too am curious about what you're trying to do. It looks suspiciously like you're mixing drawing with something completely unrelated. – kiheru Sep 05 '13 at 12:40
  • Thank you for the edit (although paintComponent should be protected), but still please address the rationale behind your request. – Hovercraft Full Of Eels Sep 05 '13 at 13:02
  • I created the button (simple JComponent), and it must first to fade out (change color after mouse released), and right after that perform `actionlistener.actionPerformed(someEvent)`. If I do `repaint(); actionlistener.actionPerformed(someEvent);` action performed before button is fully repainted. – Ernestas Gruodis Sep 05 '13 at 13:05

2 Answers2

5

Your question is:

How to know that paintComponent(Graphics g) has finished it's job?

And then you state in a comment to the question:

I created the button (simple JComponent), and it must first to fade out, and right after that perform actionlistener.actionPerformed(someEvent)

As I suspected, you appear to be doing something wrong inside of paintComponent since the driver behind the fading out should not be inside of this method. The method should be fast as all get out, it should complete in the figurative "blink of an eye", and should not have any delays or fading inside of it. Rather you'll likely use a Swing Timer to change a class field that the button uses for it's transparency, calling repaint after each change of state, and then when the Timer is done, you call your code do whatever action you desire.

For more specific help, consider creating and posting an sscce.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Whoever up-voted this, thanks! You've pushed me over the 100k mark! – Hovercraft Full Of Eels Sep 05 '13 at 13:15
  • @Ernestas Gruodis simple task for Swing TImer fading_out starting immediatelly, if ended Swing Action could be/is invoked from Swing Timer, untill fading (repeatly event from Swing Timer) ended SwingAction will be disabled by setEnable(false) – mKorbel Sep 05 '13 at 13:19
  • 2
    Ha! Now you owe me :-P Congratulations! – kiheru Sep 05 '13 at 13:20
  • Button behave like that: it is grey, then I press it and it becomes yellow. When I release it - transparency is set to zero, and the color is reset to grey, and then some action is performed (sets popup window which has this button to invisible, and do some logic). The main problem is that if I set popup to visible, for a few milliseconds I can see yellow color, then it is repainted to grey. So I must repaint/set transparency before button is set invisible, because if it is invisible, repaint/transparency is not done. – Ernestas Gruodis Sep 05 '13 at 13:28
  • Actually my method works perfectly, just trying to find the best solution. – Ernestas Gruodis Sep 05 '13 at 13:30
  • @Hovercraft Full Of Eels: Congratulations. – Gilbert Le Blanc Sep 05 '13 at 13:42
  • 4
    ............ The main problem is that if I set popup to visible, for a few milliseconds I can see yellow color, then it is repainted to grey. So I must ... == redirect whatever from [ActionListener/better Swing Action to SwingWorker](http://stackoverflow.com/a/6186188/714968), better to Runnable#Thread, then there isn't any ghosts from repainting is delayed by code in ActionPerformed – mKorbel Sep 05 '13 at 13:43
  • Yes, that was the answer I think :) – Ernestas Gruodis Sep 05 '13 at 13:56
  • 2
    Congratulations Pete @100k :) – camickr Sep 05 '13 at 14:06
  • 2
    @HovercraftFullOfEels : Congratulation on reaching the century mark :-) – nIcE cOw Sep 05 '13 at 16:25
  • @ErnestasGruodis: again, consider creating and posting an [SSCCE](http://sscce.org) if you're still stuck. Use `Thread.sleep(...)` to simulate any longer running sections of code. – Hovercraft Full Of Eels Sep 05 '13 at 18:38
1

I liked this example from SwingWorker documentation:

   final JLabel label;
   class MeaningOfLifeFinder extends SwingWorker<String, Object> {
       @Override
       public String doInBackground() {
           return findTheMeaningOfLife();
       }

       @Override
       protected void done() {
           try { 
               label.setText(get());
           } catch (Exception ignore) {
           }
       }
   }

   (new MeaningOfLifeFinder()).execute();

This simple example with a little modification could be very helpful in my situation. P.S. Does anybody know the source code of findTheMeaningOfLife(); method above?.. :))

Ernestas Gruodis
  • 8,567
  • 14
  • 55
  • 117