Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Tips on debugging drawImage()  RSS feed

 
Jim Venolia
Ranch Hand
Posts: 312
2
Chrome Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've got a program that has 2 threads. One thread generates images and puts them into a blocking queue. The other thread reads from the blocking queue and paints the image to the screen.
The display thread's main loop is:



drawLife() builds the image, paintScreen does the heavy lifting:



I've checked, neither g nor image is null. I know someone will ask, so here is drawLife():

paintTimer is a class I wrote to profile my code.

My GUI has 2 buttons: run and step. One runs at full speed, the other is a single step. The problem is, my image doesn't show up onscreen until I hit either Run or Step. If I hit step it runs 1 generation and the screen gets updated, but it shows the second generation. If I use a breakpoint and step through the code drawImage() paints the second generation. I never see the beginning condition.

I've run this in Eclipse with breakpoints all over the place. Everything works fine except my screen doesn't update until I show the second iteration.

Out of frustration I put the GUI into it's own thread, that didn't help. Eclipse shows I've now got 12 threads in my little program. All suspended waiting for something to happen, my screen is the default create screen.

Any advice on figuring out why drawImage() doesn't seem to update my screen until I hit a button?

/ I'm the guy with the "I've lost my head" thread
// How did I fix it?
/// hellifino, working on something else it suddenly started working and I'm afraid to touch the create GUI stuff.
 
Rob Camick
Ranch Hand
Posts: 2787
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


You should not do painting by using getGraphics(). Any painting you do is only temporary until Swing decides the component needs to be repainted at which time you will lose your painting. Custom painting is done by overriding the paintComponent() method of the panel and then you add the panel to the frame.

However, you don't even need to go to all that trouble. You are painting the image at is actual size, so you can just use a JLabel and add an ImageIcon to the label.

Instead for using a do while loop, you can then use a Swing Timer to schedule the changing of the Image.

 
Rob Camick
Ranch Hand
Posts: 2787
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is an example that demonstrates both of the above suggestions:


You will also need the Screen Image class to run this code as it dynamically creates a image every second.
 
Jim Venolia
Ranch Hand
Posts: 312
2
Chrome Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's an animation that gets updated every millisecond or so. PaintComponent only updates when Swing gets around to it. drawImage is what I want.

Ever notice how hard it is to type when you have a cat between you and the keyboard?
 
Campbell Ritchie
Sheriff
Posts: 55318
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cats are unlimited evil.
Why are you updating the animation every millisecond? You cannot see anything that quickly; consider updating every 20ms or similar. I do not know how quickly you can update a GUI display, but it may not be possible for it to update every millisecond.
 
Jim Venolia
Ranch Hand
Posts: 312
2
Chrome Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
He may be unlimited evil, but her sure is cute and soft

It's Conway's game of Life, I want it to go as fast as possible.
 
Campbell Ritchie
Sheriff
Posts: 55318
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Even if the display can't keep up with the game?
 
Piet Souris
Rancher
Posts: 1942
66
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
it concerns two different things:

1) updating something for display

you can do that at any pace you like

2) displaying the thing

every, say, 50th of a second, for instance when a timer fires.

If the update speed is around 1000 times per second, you may
miss 19 out of every 20 updates, but that is probably not important.
If you look at today's modern games and graphics hardware, they
are able to do updating 200 times a second, if I may believe reviews.
Yet, screen is only updated 50 times per sec.

Like Rob, I do not understand why OP is doing it in this complicated
way. As far as I can tell, only one BufferedImage would suffice.
Update it as fast as you can, and when a Timer fires, simply draw whatever
you have to your JPanel, via the 'repaint()' mechanism. He would surely not
have the difficulties that lead to this topic.

But maybe OP can explain why he does it the way he does.

Greetz,
Piet
 
Jim Venolia
Ranch Hand
Posts: 312
2
Chrome Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My math was wrong, I'm updating every 10 ms or so. When I used paintComponant the screen updated maybe once a second, the animation was horrible.

For my question the update speed is irrelevant. I need to know why drawImage doesn't actually draw the initial image. I know drawImage returns immediately, but the return value is true indicating it drew the complete image.
 
Piet Souris
Rancher
Posts: 1942
66
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, when I draw directly to the Graphics of a JPanel, that panel gets
updated as it should. Problems only when the system wants to do
a repaint. So, I have no idea.
 
Rob Camick
Ranch Hand
Posts: 2787
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I used paintComponant the screen updated maybe once a second, the animation was horrible.


Your code is wrong. I have animated 10k balls on a screen every 50ms.

I need to know why drawImage doesn't actually draw the initial image.


Post a proper SSCCE that demonstrates the problem I gave you a simple example of how to create a SSCCE. We can't guess what is going on based on a few lines of code. We don't know the context of your code. Create a simple SSCCE that just displays 1, then 2, then 3 etc. on the image. We don't care about your game if life because is irrelevant to the stated problem of just displaying an image.
 
Jim Venolia
Ranch Hand
Posts: 312
2
Chrome Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The code is over 700 lines, plus a couple ancillary files.

I know I'm doing something wrong, I'm trying to figure out what.
 
Rob Camick
Ranch Hand
Posts: 2787
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The code is over 700 lines


The detail of the code is irrelevant. The complexity of the buffered image you are creating is irrelevant.

A buffered image depicting the game of life or an image displaying an increasing number is the same thing. It is an image that you update periodically.

It is the concept that you are trying to understand. Until you understand that, you won't solve your problem.

If you can't simplify the code then I have no idea why you are asking a question. We can't possibly guess which of your 700 lines is causing the problem. We can only help you understand the concept.
 
Jim Venolia
Ranch Hand
Posts: 312
2
Chrome Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's the GUI part of my code. I could zip the entire program but I have nowhere to put it so you can get at it. The fact that I need FUDGEX and FUDGEY, plus my buttons/slider don't resize like I think they should, tells me there is something I'm not understanding here.

Rob, I've looked at your code and it's cleaner than mine. I'll be changing my stuff to use a timer instead of sleeping to control the speed. Looks like I also need to rename my Timer.java class I wrote.


 
Rob Camick
Ranch Hand
Posts: 2787
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You still miss the point of my comments.

There is no need for buttons or sliders. All you are trying to do is paint a buffered image. The game of life code is irrelevant for this and I am not even going to look at it.

Until you learn to simplify problems you won't learn how to debug code.

fact that I need FUDGEX and FUDGEY


Probably because you are using getGraphics on the frame. The frame includes the borders and title bar. You want your painting to be only on the content pane of the frame. Another reason for doing custom painting properly.

Until you learn how to create a SSCCE I can't help.
 
Jim Venolia
Ranch Hand
Posts: 312
2
Chrome Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is an SSCCE? What is ScreenImage?
 
Campbell Ritchie
Sheriff
Posts: 55318
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is an SSCCE.
 
Rob Camick
Ranch Hand
Posts: 2787
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is an SSCCE? What is ScreenImage?


Those are links that you click on.

Or you can always search the web. This is another part of problem solving.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!