2011-06-07 35 views
0

我有一个小面板,我正在通过改变它的球来移动它的x co-ordinate。 我希望球在遇到帧尾时向后移动。我的帧的宽度为 (by fr.setSize(300,300))。 现在我编程的动画,如:结束球的路径

// when x == 300 
// stop the timer 

但X = 300似乎大于它的宽度是300!这怎么可能。 **球移出300 x 300框架并变得不可见。 这是怎么发生的?

这些是最终会发生什么的屏幕截图。

Ball is moving...

Ball is no where..!!

Upon Enlarging,ball is there

第一快照是该移动高尔夫球的,第二显示球已经消失了,就扩大该球第三所示是存在的。

为什么会发生这种情况?我如何将框架的终点设置为球的终点?

+0

请提供一些代码,以便我们可以查看它。 – 2011-06-07 05:18:03

回答

2

您需要考虑组件的可见的大小。它不一定与您要求的尺寸相同。

您可以使用getSize方法来确定组件的实际大小,但您还需要致电getInsets以确定是否有任何空间已被保留供边界使用。这会给你真正的,可绘制区域:

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! 
    ... 
} 

还记得Graphics程序像fillOval画下来,并指定coodinate的权利,所以你需要想想球协调手段。它是球的中心,还是左侧或右侧?计算球是否到达可绘制区域的一侧时,您可能需要减去球的宽度。

2

你球的“x坐标”可能是它的左上角边界吗?这可以解释为什么它只是在框架之外移动。还要考虑到你的框架周围有一些装饰像素。

也许你需要适应像

if (x == framewidth - decorationwidth - ballwidth) stopAnimation(); 
2

x坐标点到图像的左上角?如果是这样,当x == 300时,图像的其余部分将已经在框架外。您必须从等式中减去图像的宽度。

0

你必须得到RectanglepaintComponent(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); 
    } 
} 
+1

+1用于发布可测试的解决方案。我们都知道,为了制造“RED”球,它的反弹速度更快。 ;)顺便说一句 - 稍微调整一下源代码到'EXIT_ON_CLOSE'这个'JFrame' - 来杀死'Timer'线程。 – 2011-06-07 07:16:07

1

这是条件

if (end > (frameWidth-ballWidth)) // end is any integer 
    // stop the timer or do whatever 

注意,X坐标和椭圆的y坐标是在oval.Therefore的中心,你需要从边框的宽度减去球宽度。