问题
I have a small panel where i am making a ball to move by just varying it's x co-ordinate
.
I want the ball move back when it encounters the end of frame.The width of my frame is 300
(by fr.setSize(300,300))
.
Now I programmed the animation like :
// when x == 300
// stop the timer
But x=300 seems to be greater than it's width which is 300 ! How is this possible.
**The ball moves out of the 300 x 300
frame and becomes invisible.
Why is this happening ?
These are the screen shots of what happens eventually.
First snapshot is that of the moving ball,second shows that ball has disappeared,third shows on enlarging that ball is there.
Why this happens.? How can i set the frame's end point as the ball's end point?
回答1:
You need to consider the viewable size of your component. It won't necessarily be the same as the size you requested.
You can use the getSize
method to determine the actual size of your component, but you also need to call getInsets
to find out if any space has been reserved for use by borders. This will give you the real, drawable area:
public void paint(Graphics g) {
Dimension size = getSize();
Insets insets = getInsets();
int available = size.width - insets.left - insets.right;
// Draw stuff. Remember to offset by insets.left and insets.top!
...
}
Also remember that Graphics
routines like fillOval
draw down and to the right of the coodinate you specify, so you need to think about what the ball coordinate means. Is it the center of the ball, or the left or right side? You may need to subtract the width of the ball when calculating whether it has reached the side of the drawable area or not.
回答2:
Is the "x-coordinate" of you ball maybe its top-left border? This would explain why it move just outside the frame. Also take into consideration that you frame has some pixels of decoration around.
Maybe you need to adjust to something like
if (x == framewidth - decorationwidth - ballwidth) stopAnimation ();
回答3:
The x coordinate points to the top-left corner of the image? If so, when x == 300, the rest of the image will be out of the frame already. You have to subtract the image's width from the equation.
回答4:
This is the condition
if ( end > (frameWidth-ballWidth) ) // end is any integer
// stop the timer or do whatever
Note that x-coordinate and y-coordinate of the oval are centers of the oval.Therefore you need to subtract ball width from the frame width .
回答5:
You have to get Rectangle
for paintComponent(Graphics g)
.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AnimationJPanel extends JPanel {
private static final long serialVersionUID = 1L;
private int cx = 0;
private int cy = 150;
private int cw = 20;
private int ch = 20;
private int xinc = 1;
private int yinc = 1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
AnimationJPanel panel = new AnimationJPanel();
panel.setPreferredSize(new Dimension(400, 300));
panel.animate();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public AnimationJPanel() {
setLayout(new BorderLayout());
JLabel label = new JLabel("This is an AnimationJPanel");
label.setForeground(Color.RED);
label.setHorizontalAlignment(SwingConstants.CENTER);
add(label);
setBackground(Color.BLACK);
setForeground(Color.RED);
setOpaque(true);
}
public void animate() {
new Timer(15, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Rectangle oldCircle = new Rectangle(cx - 1, cy - 1, cw + 2, ch + 2);
cx += xinc;
cy += yinc;
if (cx >= getWidth() - cw || cx <= 0) {
xinc *= -1;
}
if (cy >= getHeight() - ch || cy <= 0) {
yinc *= -1;
}
repaint(oldCircle);
repaint(cx - 1, cy - 1, cw + 2, ch + 2);
}
}).start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(cx, cy, cw, ch);
}
}
来源:https://stackoverflow.com/questions/6260821/ending-the-balls-path