Java 弹球小程序
我让小程序弹起球,在类Java 弹球小程序,java,swing,animation,Java,Swing,Animation,我让小程序弹起球,在类Ball.java中,我用方法repaint()创建了内部类TimerListener,当我运行小程序时,java不重新绘制球,而是一次又一次地绘制球(不是删除,然后绘制) 这是我的类Ball.java import javax.swing.Timer; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Ball extends JPanel { private i
Ball.java
中,我用方法repaint()
创建了内部类TimerListener
,当我运行小程序时,java不重新绘制球,而是一次又一次地绘制球(不是删除,然后绘制)
这是我的类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);
}
}
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());
}
});
}
}
计时器不也应该改变球对象的位置吗?换句话说,它不应该改变它的x和y值吗?i、 e
private class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
// first change x and y here *****
repaint();
}
}
否则,球应该如何移动才能减少反弹
您的paintComponent(…)
方法中似乎有此更改位置代码,这并不好,因为您无法完全控制何时甚至是否调用此方法。因此,更改此对象状态的程序逻辑和代码不属于该方法的内部
此外,您的
paintComponent(…)
方法重写需要在其第一行调用super的paintComponent(…)
方法,以便在绘制新球之前可以擦除旧球。计时器不也应该更改球对象的位置吗?换句话说,它不应该改变它的x和y值吗?i、 e
private class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
// first change x and y here *****
repaint();
}
}
否则,球应该如何移动才能减少反弹
您的paintComponent(…)
方法中似乎有此更改位置代码,这并不好,因为您无法完全控制何时甚至是否调用此方法。因此,更改此对象状态的程序逻辑和代码不属于该方法的内部
另外,您的
paintComponent(…)
方法重写需要在其第一行调用super的paintComponent(…)
方法,以便在绘制新球之前可以擦除旧球。@user1906377:是,我知道这就是我建议您这样做的原因。@user1906377:但不要试图从paintComponent中更改位置,因为这不是一个好方法。您无法完全控制何时或是否调用paintComponent。将更改位置代码移到计时器上。@user1906377另请参见此@user1906377:是的,我知道这就是我建议您这样做的原因。@user1906377:但不要尝试从paintComponent内更改位置,因为这不是一个好方法。您无法完全控制何时或是否调用paintComponent。将更改位置代码移动到计时器。@user1906377另请参见此