ending the ball's path

故事扮演 提交于 2020-01-06 10:20:21

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!