Basically, nothing is moving the ball.
Each time the Swing Timer
ticks, all you do is repaint.
You need to move the movement logic to the actionPerformed
method of the ActionListener
registered to the Timer
More like...
public void StartBouncingBallTest() {
timer.start();
}
//...
class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (x > 0 && y > 0) {
x += dx;
y += dy;
}
else if (x == 0) {
x -= dx;
y += dy;
}
else if (y + (2 * radius) > getHeight()) {
x += dx;
y -= dy;
}
else if (y == 0) {
x += dx;
y -= dy;
}
else if (x + (2 * radius) > getWidth()) {
x -= dx;
y += dy;
}
repaint();
}
}
This way, each time the Timer
ticks, you are making update the position of the ball accordingly...
Updated with working example
I made two changes. I made your TimerListener
an inner class of Ball
, which allows it to access the variable and methods of Ball
and modified your movement logic so it works
class Ball extends JPanel {
private int radius = 10;
private int x;
private int y;
private int dx = 3;
private int dy = 3;
private Timer timer = new Timer(20, new TimerListener());
public void StartBouncingBallTest() {
timer.start();
}
public void StopBouncingBallTest() {
timer.stop();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval(x, y, 2 * radius, 2 * radius);
}
class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (x < 0 || x + (2 * radius) > getWidth()) {
dx *= -1;
}
if (y < 0 || y + (2 * radius) > getHeight()) {
dy *= -1;
}
x += dx;
y += dy;
repaint();
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…