Reputation: 2183
I was suggested not to use sleep
for pausing purpose and instead use swing
timer
but still its not working.The animation i want to achieve is a ball travelling from the top left corner diagonally towards the bottom.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class Show_starter {
int x, y;
JFrame window = new JFrame("Graphic_show");
Graphic_panel jp = new Graphic_panel();
public static void main(String[] args) {
Show_starter start = new Show_starter();
start.go();
}
private void go() {
window.getContentPane().add(BorderLayout.CENTER, jp);
window.setSize(600,800);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class Graphic_panel extends JPanel {
public void paintComponent(Graphics g) {
for ( int i = 0; i < 100; ++i) {
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
x++;
y++;
try {
Timer tmr = new Timer(1000, new TimerListener()); //This fires an event after every 1 sec after it has started by start().
//But The ball travels too much fast and stops at a point and again travels very fast.
tmr.serRepeats(false); // even this is not working.
tmr.start();
//should i use repaint here or in Listener for this timer?
} catch (Exception e){}
}
}
class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
jp.repaint();
}
}
}
}
The behaviour it is showing is very odd ball first goes at very high speed and stops momentarily at a point and again moves at same speed.
I have also tried to change the time for timer
event to fire but the same thing happens.
Even inside loop where I have started timer
the follow function call is not working
setRepeats(false);
Upvotes: 1
Views: 346
Reputation: 9872
don't create new timers always one timer is enough .decrees timing interval bit more .1 second is too slow for a animation.you don't need a loop and don't increment x and y inside paintcomponet()
method because this method get called for some reason for example when you resize,minimize,maximize.
the unexpected behavior is due to your loop and creating new timers(). for example in x y start at zero but in first second x y increased to 100,100 in next paint you see them in a 100,100 position .that's look like quick move and then stop ...
example code (edited)
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Show_starter {
private Timer tmr;
int x, y;
JFrame window = new JFrame("Graphic_show");
Graphic_panel jp = new Graphic_panel();
public static void main(String[] args) {
Show_starter start = new Show_starter();
start.go();
}
private void go() {
window.getContentPane().add(BorderLayout.CENTER, jp);
window.setSize(600, 800);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tmr = new Timer(10, new ActionListener() { // time gap in millisecond
@Override
public void actionPerformed(ActionEvent ae) {
jp.increse();
jp.repaint();
}
});
tmr.start();
}
class Graphic_panel extends JPanel {
public void increse() {
x++;
y++;
if (x > 100) { // stop animation at x>100
tmr.stop();
}
}
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
}
}
output (smoother than that)
Upvotes: 2
Reputation: 299
Firstly you should not use a loop
inside paint component
.
public void paintComponent(Graphics g){
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
Just draw it and make x
and y
public in the class so that you can easily access from outside
Now run a runnable
(consult invokelater
and swingUtilities
) or create a new Thread
inside public void run()
do whatever animations you want to do . You can use a loop but add Thread.sleep(//in miliseconds)
and repaint()
in each iteration .
note : you need to change the x
and y
and repaint()
so that it is drawn in a new position. And the sleep()
is needed to slow down the execution otherwise it can't be visible to viewer.
Upvotes: 0