我制作了小程序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());
}
});
}
}
答案 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(...)
方法,以便在绘制新球之前擦除旧球。