Bouncing Ball applet

Mik*_*kky 1 java animation swing

我制作了小程序弹跳球,在课堂上Ball.javaTimerListener用方法制作了内部类repaint(),当我运行小程序时,不是重新绘制球,而是一次又一次地绘制球(不删除,然后绘制).

这是我的课程代码 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);
}   
}
Run Code Online (Sandbox Code Playgroud)

这是我的课程代码 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());
        }
    });

}
    }
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 5

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

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

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

        repaint();
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,球怎么会移动得更少?

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

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