wood burning stoves 2.0*
The moose likes Swing / AWT / SWT and the fly likes Unable to draw shapes beyond the margins of a JPanel Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Unable to draw shapes beyond the margins of a JPanel" Watch "Unable to draw shapes beyond the margins of a JPanel" New topic
Author

Unable to draw shapes beyond the margins of a JPanel

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39053
    
  23
In our MSc class we had an exercise to draw a ball (g.drawOval()) which flies around inside a container and bounces off whenever it hits the margins of the container.
So I did it. My ball bounced off the right-side and bottom of the container, going approx half its width beyond the margin of the container, then bouncing back. Since I had given it a setCentreX() and a setCentreY() method, this is exactly how I had hoped it would behave.
But on the top and left margins of the container it takes a different path; rather than this sort of path
/
\
it seems to slide along the edge of the container, rather like this
/
|
\ . . . only it is awkward to draw on screen.
This came as a surprise, so I tried another GUI, with sliders on, to move the centre X and centre Y of a shape, and it wouldn't move beyond the left or top margins of the container (a JPanel, actually). It was quite easy, on the other hand, to resize the window so the shape fell off the right or bottom of the panel.
I looked up the drawOval() method of java.awt.Graphics, and it gives four int values for x, y, width, height, and doesn't say anything about negative values of x and y being prohibited, even though that seems to be what is happening.

Does anybody know anything about this?
CR
Craig Wood
Ranch Hand

Joined: Jan 14, 2004
Posts: 1535
Your boundry-checking code does this. Do the boundry check before the ball gets to the edge of the drawing surface and reverse the direction. The 'stuck' behavior comes when it moves (slightly) out of bounds and deosn't know what side it is on, ie, left or right; zero to getWidth.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39053
    
  23
Thank you. I shall post the bit of the code which checks the boundary, but can't do it until later.
CR
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39053
    
  23
Hello. I'm back.
I don't actually have a check for when the shape passes the boundary. What I have is floatX which represents its position (and it is actually declared as a float), and I have a (javax.swing.)Timer, which calls repaint() every 25ms. In paintComponent(Graphcs g), you find the following, which increments floatX by (a randomly-set) xSpeed, then sets the centre of the circle to floatX. If the central x crosses the boundary of the JPanel, the speed changes sign. If count is more than 2000, it invokes System.exit(0), so the whole application closes automatically after about 1 min 20 sec.

And you have the same sort of thing for Y.
Now, the circle is set up as radius = 25f, and the setCentreX() method looks like this:and the drawYourselfSolid method reads:
so I don't think there is anything which actually checks the crossing of the boundary.
The if statements test when the centre of the circle crosses the left or top boundary of the JPanel, by which time the left side of the circle is 25px beyond the edge of the panel.

So, no, I am not checking for when it corsses the boundary. How ought I to check for crossing the boundary?

No more replies from me before tomorrow morning.

Thank you.
CR
Craig Wood
Ranch Hand

Joined: Jan 14, 2004
Posts: 1535
You check the boundry limits inside 'paintComponent':

After incrementing the floatX, if the incrementing puts it out of bounds, ie, < 0 || > width, you toggle the xSpeed direction. On the next trip through 'paintComponent' if the next incrementing is not enough to get us back in bounds the direction is toggled again and the oval seems to vibrate back and forth at the boundry, trapped.
To avoid this try checking for boundry penetration before incrementing and with the increment:

In general it is recommended that we limit the code in 'paintComponent' to rendering. The rendering can be controlled by variables that are manipulated in the event code.
This checking/incrementing is better placed inside your ActionListener or the method it calls to do the animating.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39053
    
  23
Thank you. I shall try that. Better design to have the calculations moved elsewhere.

I have also tried a plain JPanel with a circle which walks across the screen, an dthis seems to disappear off the left margin of the screen quite happily.

There is the possibility that I have done what it says in the books to do, namely somewhere put a check on my methods, so there might be some method somewhere which restricts the ability of the x and y variables of the circle to go negative. That would explain why my circle doesn't cross the boundaries.

BTW: Isn't there supposed to be an embarrassed face graemlin? I have seen it on another website.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39053
    
  23
Thank you for your help. I have moved the position updating code into a different method.
And I had put a restraint against negative positions and forgotten about it. I feel a right fool now.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Unable to draw shapes beyond the margins of a JPanel