Bouncing Ball applet

时间:2012-12-23 11:57:01

标签: java swing animation

我制作了小程序Bouncing Ball并在课程Ball.java中使用方法TimerListener创建了内部类repaint(),当我运行applet时,不是重新绘制球,而是绘制球一次又一次(不删除,然后画)。

这是我的课程Ball.java

的代码
import javax.swing.Timer;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Ball extends JPanel {
private int delay = 10;

Timer timer=new Timer(delay, new TimerListener());

private int x=0;
private int y=0;
private int dx=20;
private int dy=20;
private int radius=5;

private class TimerListener implements ActionListener{
    public void actionPerformed(ActionEvent e) {
        repaint();
    }
}

public void paintComponent(Graphics g){

    g.setColor(Color.red);
    if(x<radius) dx=Math.abs(dx);
    if(x>(getWidth()-radius)) dx=-Math.abs(dx);
    if(y>(getHeight()-radius)) dy=-Math.abs(dy);
    if(y<radius) dy=Math.abs(dy);
    x+=dx;
    y+=dy;
    g.fillOval(x-radius, y-radius, radius*2, radius*2);
        }
public void suspend(){
    timer.stop();
}
public void resume(){
    timer.start();
}
public void setDelay(int delay){
this.delay=delay;
timer.setDelay(delay);
}   
}

这是我的课程BallControl.java

的代码
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class BallControl extends JPanel{

private Ball ball = new Ball();
private JButton jbtSuspend = new JButton("Suspend");
private JButton jbtResume = new JButton("Resume");
private JScrollBar jsbDelay = new JScrollBar();

public BallControl(){
    JPanel panel = new JPanel();
    panel.add(jbtSuspend);
    panel.add(jbtResume);
    //ball.setBorder(new javax.swing.border.LineBorder(Color.red));
    jsbDelay.setOrientation(JScrollBar.HORIZONTAL);
    ball.setDelay(jsbDelay.getMaximum());
    setLayout(new BorderLayout());
    add(jsbDelay, BorderLayout.NORTH);
    add(ball, BorderLayout.CENTER);
    add(panel, BorderLayout.SOUTH);

    jbtSuspend.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            ball.suspend();
        }
    });

    jbtResume.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            ball.resume();
        }
    });

    jsbDelay.addAdjustmentListener(new AdjustmentListener() {
        public void adjustmentValueChanged(AdjustmentEvent e) {
            ball.setDelay(jsbDelay.getMaximum() - e.getValue());
        }
    });

}
    }

1 个答案:

答案 0 :(得分:5)

Timer不应该也改变Ball对象的位置吗?换句话说,是不是应该改变它的x和y值?即,

private class TimerListener implements ActionListener{
    public void actionPerformed(ActionEvent e) {

        // first change x and y here *****

        repaint();
    }
}

否则,球怎么会移动得更少?

您似乎在paintComponent(...)方法中有此更改位置代码,这并不好,因为您无法完全控制何时或甚至调用此方法。因此,更改此对象状态的程序逻辑和代码不属于该方法。

此外,您的paintComponent(...)方法覆盖需要在第一行调用超级paintComponent(...)方法,以便在绘制新球之前擦除旧球。