Reputation: 53
So all i'm trying to do is make a ball bounce around a window, but for some reason, while no red flags are raised on eclipse, when i run it, it just displays a static ball.
This is what i got so far:
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Pong extends JPanel implements ActionListener {
int x=600, y=250, vx=5, vy=5;
public static void main(String[] args) {
// TODO Auto-generated method stub
Pong p = new Pong();
JFrame f = new JFrame();
f.setSize(1400, 700);
f.add(p);
f.setVisible(true);
Timer t = new Timer(100, p);
t.start();
t.addActionListener(p);
}
public void paintComponent(Graphics b){
b.fillOval(x,y, 50, 50);
}
@Override
public void actionPerformed(ActionEvent e) {
if(y>700||y<0) {
vy=-vy;
}
if(x>1400||x<0) {
vx=-vx;
}
y=y+vy;
x=x+vx;
}
}
Upvotes: 2
Views: 2962
Reputation: 3912
You need to add a call to repaint()
at the end of actionPerformed
. Note that this will lead to other painting problems (the ball just gets smeared across the screen) because you also need to call super.paintComponent(b);
as the first thing in your paintComponent
method.
Also there is no need to call t.addActionListener(p)
, as the ActionListener
has already been added by the call to new Timer(100, p)
. Since the ActionListener
is now actually added twice, actionPerformed
gets called twice per timer pop and your ball moves two times faster than you intended.
Note also that as you currently have it, the process will never end until it is killed. You need to make sure you dispose of your JFrame:
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
and shutdown your Timer
:
final Timer t = new Timer(100, p); // need to make this final to avoid compile error
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
t.stop();
}
});
I noticed that I had a bunch of "Pong" processes still running after testing your code. :)
Upvotes: 3
Reputation: 238
You should call repaint after you modify a location. for example
public void actionPerformed(ActionEvent e) {
if(y>700||y<0) {
vy=-vy;
repaint();
}...
Upvotes: 0
Reputation: 2146
You need to call repaint on the JPanel
or it will not have any reason to repaint itself.
public void actionPerformed(ActionEvent e) {
...
this.repaint(this.getVisibleRect());
}
(untested)
Upvotes: 0
Reputation: 691645
The timer must ask the panel to repaint itself:
public void actionPerformed(ActionEvent e) {
...
repaint();
}
Upvotes: 4