• 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
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Carey Brown
  • Mikalai Zaikin
Bartenders:
  • Lou Hamers
  • Piet Souris
  • Frits Walraven

repaint not calling paintComponent

 
Greenhorn
Posts: 6
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Very frustrating day - spent all day trying to figure this out. I am merely trying to have the animated ball bounce around a box. I was trying more complicated stuff but 'simplified' to better understand. Now not working and I dont know why. After much searching and reading I will give this a try.
I have the CirclePanel extend JPanel, and have the ball in separate class (other project has a balls array and multiple balls, but keep this one simple). I initialize the ball and move it around. I use drawCircle to send calls to repaint (just like in the swing tutorials). I override the paintComponent method, and use the draw methods in my ball.
The problem I'm having is that repaint never calls the paintComponent. I put in a lot of primitive debug println. When the frame is first set visual, there is a call to paintComponent (actually twice) and the frame with dark green background and big red ball in the upper left corner appears. But it never moves. When I print out the coordinates for the ball, they are moving nicely. If I add a specific draw command in the drawCircle method, it draws the ball moving all over the panel like I wanted.
It seems there is a catch-22: repaint calls paintComponent when something needs to be changed. But if you put the code to draw in the paintComponent method, nothing has changed yet, so it doesn't need to call paintComponent, so nothing gets drawn!
I can't see the difference between my code and the code in SwingPaintDemo4 - and yet somehow it magically calls paintComponent to make a change that hasn't happened yet. I have another program with 100 balls bouncing around that to my eye is exactly like this one and it works fine. I'm at a loss. Hopefully I'm missing something simple.

Another issue - if I remove the JOptionPane line - the frame is blank white! With the pause for the JOptionPane the frame is green with a red ball. Is this a clue?

I have a lot of extra variables and things specifically initialized to try and figure out what was going on. (I looked all over for instructions on how to insert code but can't find anything - hope the code button up there and copy/paste works - oh the preview function helped me to finally get it right)

 
Marshal
Posts: 79655
381
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

I have moved you to our GUIs forum, where we usually discuss such questions.

Don't use Thread#sleep. Remember Swing components are not thread‑safe, so you mustn't access them from two threads. So any attempt to make the thread sleep may stop everything else. It does not simply delay the painting. Use a Timer instead.
What may be happening is that the duration when the thread is active is too short for all the repainting, which takes several milliseconds. If you use a JOptionPane, that takes the focus away from the panel and the time it takes you to dismiss the option pane allows the painting to complete.

Where are you calling a method to move the circle? I can see calls to paint circles but where do you reset its position?

Some of the variable names are poor; in the circle constructor for example you cannot tell that d means diameter. Space out your code. Don't write x+d/2 but x + d / 2.
 
Marshall Crenshaw
Greenhorn
Posts: 6
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks.

Where are you calling a method to move the circle? I can see calls to paint circles but where do you reset its position?


It was 'hidden' at 135 inside drawCircle - not very logical place to put it, result of moving things around to try and get it to work since I didn't understand what was wrong. I thought if I put it in there the system would 'magically' realize I was moving the circle and call paintComponent or something. Illogical thinking naturally leads to illogical results.

Some of the variable names are poor; in the circle constructor for example you cannot tell that d means diameter. Space out your code. Don't write x+d/2 but x + d / 2.



My first reaction was "Yes sir, sheriff sir." Problem with authority I guess. Then I took a breath and thought Sheriff must have a reason for everything, so try and figure it out (hopefully not an erroneous assumption).
Could be obsessive compulsive and wants everything his way. Or could be it will help me in the long run.
I read through the style guide. Looked around the site at more posted code - gave me a headache trying to look at all that stuff.
Not having a clue how to fix it, I started editing my code to match the style guide. Huh, looks nicer. Easier to read. No headaches. Easier to find stuff. Fewer mistakes. Thanks sheriff.

Don't use Thread#sleep. Use a Timer instead.


Yeah I read that somewhere, but it was easier to throw the Thread#sleep in there than figure all that stuff out with Timer and ActionListener so I just threw it in (when it was working too fast and everything a blur). I believe was before I used invokeLater too.
Notice that sneaky blue line under Timer linking to tutorial - since I'm waiting on a "real" reply to my message to help I might as well check that out. Time spent puzzling out how to implement ActionListener and then know that means I have to override ActionPerformed using an ActionEvent which has a getActionCommand() method...).

Suddenly it works - my little ball is bouncing around. Using thread#sleep was like unsafe sex leading to bad consequences. Also let me add a Start and Stop button which I wasn't able to do in the past.
Now I got to understand all that thread stuff...

I'll post working code. Thanks. Maybe I should try the Cattle Drive - would it help me learn this stuff better?

 
Campbell Ritchie
Marshal
Posts: 79655
381
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Every now and again I give some good advice. Not very often … but well done sorting it out
As you have seen, the style guides may appear tedious but once you get into the habit of using them, your code is much easier to understand.
 
Talk sense to a fool and he calls you foolish. -Euripides A foolish tiny ad:
We need your help - Coderanch server fundraiser
https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic