Only 48 hours left in the trailboss' kickstarter!

New rewards and stretch goals. CLICK HERE!



  • Post Reply Bookmark Topic Watch Topic
  • New Topic

repaint() is automatically "erasing" the old circle?  RSS feed

 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
On page 385 in Chapter 12 this code is shown to eliminate "smearing":



I had done all the previous code (in my own style) and found that the background rectangle was either being redrawn on its own, or there was something else removing the old circles from the screen. I then typed in the code from the previous page exactly as it was, to see if I had some change in syntax that would cause this, and it did the same thing.

Here's my code:


Is this because I'm using JRE7? I can't find any documentation that indicates the repaint() method has changed since Java 5.
 
Rob Camick
Ranch Hand
Posts: 2752
11
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Instead of using the first two lines you should just be using:



Then you can use the setBackground(...) method of the component to specify thebackground color.
 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not sure you fully read my post. The gist of it is: The code in the book is not behaving the way the book says it should. Was there a change to repaint() in Java 6 or 7 that would cause this?
 
Rob Spoor
Sheriff
Posts: 20893
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Which book are you talking about? And have you checked for an errata list?
 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Head First Java
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 36393
453
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan posted some additional info in his other post

I also did a screen record to show the problem that I'm seeing:
https://www.youtube.com/watch?v=-x048ZM4nFY


The reason I'm so persistent is that the new project, the music video one, is relying on the behavior.
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 36393
453
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan,
When I ran your code with Java 7 on a Mac, it showed the "history" of the orange circle and didn't "erase" it. I wonder if there is a bug in one of the implementations of the JDK.
 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeanne Boyarsky wrote:Ryan,
When I ran your code with Java 7 on a Mac, it showed the "history" of the orange circle and didn't "erase" it. I wonder if there is a bug in one of the implementations of the JDK.


Thank you for testing that for me!

Which version of the JDK are you using?
Which version of OSX are you running?
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 36393
453
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
java 1.7.0_05

OS X (10.9.1)
 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeanne Boyarsky wrote:java 1.7.0_05

OS X (10.9.1)


Thank you!

I have java 1.7.0_51, so maybe they broke something in a newer release.

Thanks again for the help!
 
Rob Camick
Ranch Hand
Posts: 2752
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I ran your code with Java 7 on a Mac, it showed the "history" of the orange circle and didn't "erase" it. I wonder if there is a bug in one of the implementations of the JDK.


That is not a bug.

That is what should happen when you don't use super.paintComponent() first to clear the background.
 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Camick wrote:
When I ran your code with Java 7 on a Mac, it showed the "history" of the orange circle and didn't "erase" it. I wonder if there is a bug in one of the implementations of the JDK.


That is not a bug.

That is what should happen when you don't use super.paintComponent() first to clear the background.


The bug is that it IS erasing it when I run it. I am using a version of Java that is 46 builds newer, the bug seems to have occurred in there somewhere.
 
Rob Camick
Ranch Hand
Posts: 2752
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I really don't understand the point of this question.

Read the article on Painting in Swing. The key point regarding this question is the following:

If a Swing component's opaque property is set to true, then it is agreeing to paint all of the bits contained within its bounds (this includes clearing it's own background within paintComponent()), otherwise screen garbage may result.

Note the "screen garbage may result".

Therefore the implementation can be different on different versions/platforms.

If the code is done properly, it will not be an issue. Therefore you should always invoke super.paintComponent(), or if you extend from JComponent then I believe you need to fill the background yourself using the fillRect() method.
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeanne Boyarsky wrote:Ryan posted some additional info in his other post

The reason I'm so persistent is that the new project, the music video one, is relying on the behavior.


But as you've seen, the behaviour that you are relying on is in fact unreliable. Questions like "Did this change between version X and version Y" don't get you anywhere because the answer (whether it's Yes or No) doesn't lead to a course of action which solves your problem. You weren't planning on telling people that to use your application they have to use some specific Java versions, were you?
 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:
Questions like "Did this change between version X and version Y" don't get you anywhere because the answer (whether it's Yes or No) doesn't lead to a course of action which solves your problem. You weren't planning on telling people that to use your application they have to use some specific Java versions, were you?


Clearly you haven't read the entire post.

a) If it is a result of a change in the version, then it does solve my problem. I will be able to use an older version to get the desired behavior - I want the "history" of the shapes that are drawn.
b) This is content from Head First Java, not some project I'm going to be publishing.

Thank you again, Jeanne, for providing helpful/useful responses. Unfortunately you're the only one that has actually read my post and responded accordingly.
 
Piet Souris
Rancher
Posts: 1782
54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan,

keep it calm. The problem is not that Java has changed in some way between versions, but that you do not know
what is going on.

First of all: in your start-method you draw a number of orange circles. That works, I've just run your code.
What happens next is: the start-method is then finished, and anything that wil happen next now
fully depends on the 'paintComponent' method of your special panel.
Now, if you simply drag your window around, then, because of Java's double buffering, you will
not notice anything special, But try to resize your panel. As soon as you do that, you see all the
circles disappear. That is because Java creates a new buffer in the background, initialised
to the default background. Then it issues your 'paintComponent' method, and the only
thing that it does is to draw an orange circle with the top left at location 600,600,
so that the circle (and it is only one circle), is drawn outside of the panel. I.e: you will
see nothing.

Now, I'm not sure what this application is supposed to do, but you must improve
your 'paintComponent' somewhat.

Greetz,
Piet
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 36393
453
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan J McCormick wrote:
a) If it is a result of a change in the version, then it does solve my problem. I will be able to use an older version to get the desired behavior - I want the "history" of the shapes that are drawn.
b) This is content from Head First Java, not some project I'm going to be publishing.


Ryan J McCormick wrote:Thank you again, Jeanne, for providing helpful/useful responses.

You're welcome. I do agree with the others that if you were actually writing the program for consumption that you'd want to use different code. (I don't remember much Swing; I just tried the example.)

I also think it is useful information that the code in Head First Java happens to work on some configurations which would explain why there isn't an errata listed for it.
 
Rob Camick
Ranch Hand
Posts: 2752
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unfortunately you're the only one that has actually read my post and responded accordingly.


Seriously? I have given you plenty of advice which you are not listening to. I gave you the information in my last posting stating that it is the responsibility component to make sure the background is repainted, otherwise there can be painting artifacts. The fact that (incorrectly written) code happens to do something the way you want it to on a certain platform/version is not something you should rely on.

In this case you are NOT following the standards and sometimes it does what you want and sometimes it doesn't . It is not relevant if the code changed between versions, as it is not something that should be relied upon as the code could easily change back in the next version. The simple answer is to follow the standards and then it will always work.

Questions should be asked when you follow the standards and the code does not work as expected.

I want the "history" of the shapes that are drawn.


That is the first time you have actually posted a requirement in this question. That should have been stated with the original question. The common approach for this is to draw to a BufferedImage and then paint the BufferedImage in the paintComponent() method.
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 36393
453
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Before anyone else replies, deep breath. There are two conversations in this thread.

Rob is giving good advise one how the code should be. Form a learning point of view, this is important. Even though this wasn't the question that was asked, it is more important than the question that was asked and perfectly appropriate. I answered with a possible explanation of why the book didn't catch an error. I agree with Rob that Ryan shouldn't code the way the book suggests.

If there are any more posts about whether someone did or didn't read the code, this thread will be locked.
 
Ryan J McCormick
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeanne Boyarsky wrote:Before anyone else replies, deep breath. There are two conversations in this thread.

Rob is giving good advise one how the code should be. Form a learning point of view, this is important. Even though this wasn't the question that was asked, it is more important than the question that was asked and perfectly appropriate. I answered with a possible explanation of why the book didn't catch an error. I agree with Rob that Ryan shouldn't code the way the book suggests.


Is there any documentation on the differences between proper coding conventions and the ones in the book? I'm only 2/3 of the way through the book and, if it's already starting to diverge, I'm worried that by the end of the book one of the following will happen:
a) My environment will not be behaving in the same manner that the book expects and I will spend hours "debugging" code that is actually correct
b) My environment's behavior will differ so much from the expected behavior that the rest of the book will be useless
c) I'm going to learn coding techniques from the book that should not be used

I hope you can see why I'm so fixated on this specific issue. I'd like to get my computer to be able to run the code the book is teaching the way the book expects so that I can finish the book. Once I'm done with the last third, I can go back and teach myself about things like BufferedImages.
 
Rob Camick
Ranch Hand
Posts: 2752
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I hope you can see why I'm so fixated on this specific issue.


You are incorrectly fixated on this issue. You are attempting to take a short cut because some code happened to work the way you wanted in one version. You should NEVER write code with assumptions like that.

According to your comments, the book says that the following will eliminate smearing:



That is in fact true.

However, that does not mean that the opposite is true. It does NOT mean that if you remove those two lines you will be guaranteed to have smearing.

I pointed you to an article that specifically states you may have artifacts. You should never assume this will happen and you should not write your code that way.

Is there any documentation on the differences between proper coding conventions and the ones in the book?


I have not read the book so I can't comment, but again the general rule is that if the book states something positive, don't assume that the negative is true. You should always code to positive examples.

You are attempting to do "incremental painting". You should rely on your code to do this. There are two common ways to do this:

1) I have already mention painting incrementally on a BufferedImage and then just paint the image in the paintComponent() method
2) Keep a List of Objects to paint. Then you can incrementally add an object to the List and in the paintComponent() method you simply paint all the Objects contained in the List.

Either of the above approaches will work on any version/platform.
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan, it's unfortunate that you have been blind-sided by a minor error in a well-respected book. But now I think it's time to move on. There are five stages in this process: denial, anger, bargaining, depression, and acceptance. So far in this thread I've seen the first three. So you're nearly there. Rob Camick may have a posting style which doesn't help with the psychological process but his technical advice is right on, once you're ready to accept it.
 
Piet Souris
Rancher
Posts: 1782
54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't see where the code in the book is wrong. But that code is about preventing the smearing.

Ryans intention is to have precisely this smearing. That's okay, but the way he tried to achieve this is wrong:
by removing these two famous lines of the code.

It is exactly as Rob described in a poetic way: if programming to the positive works, then do not
expect that programming to the negative also works! ;)

@Ryan
Don't despair. I have never read this book myself, but heard good things about it. Since it states
that they will handle Threads in chapter 15, I guess that chapter 13 will be involved with
a lot more about painting. So, be patient, millions of people have mastered this subject, and in short
you will be one of them.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!