1

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

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

}
    }
4

1 回答 1

5

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

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

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

        repaint();
    }
}

否则,球应该如何移动更少反弹?

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

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

于 2012-12-23T11:58:59.503 回答