i hope you can modify my simple bouncing ball :(
its flickering.... i dont know how to solve it.

import javax.swing.*; // For JPanel, etc.

import java.awt.*;           // For Graphics, etc.
import java.awt.event.*;
import java.awt.geom.*;      // For Ellipse2D, etc.
//import java.util.*;
import java.io.*;
import java.util.Random;



public class aball extends JFrame
{
	static Graphics g;
	static int x = 5;
	static int y = 30;
	Timer timer;
	Timer timerDown;
	Timer timerUp;
	Timer timerLeftRight;
	Timer timerLeft;
	Timer timerRight;
	public aball()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		setSize(500,300);
		setLocationRelativeTo(null);
		setBackground(Color.blue);
		add(new modJPanel());
		
		timer = new Timer(10, new ActionListener()
		{
			public void actionPerformed(ActionEvent ae)
			{
				timerLeftRight.start();
				if(y >= getHeight())
				{
					up();
					System.out.println("go up!");
					timer.stop();
				}
				else
				{
					down();
					System.out.println("go down!");
					timer.stop();
				}
				setTitle("" + y + " HEIGHT!!!: " + getHeight());
				repaint();
			}
		});
		timer.start();
		
		timerDown = new Timer(1, new ActionListener()
		{
			public void actionPerformed(ActionEvent ae)
			{
				
				y +=4;
				repaint();
				setTitle("Y: " + y + " HEIGHT: " + getHeight() +  " X: "  + x + " WIDTH: " + getWidth());
				if(y > getHeight() - 25)
				{
					timerDown.stop();
					timerUp.start();
				}
			}
		});
		
		timerUp = new Timer(1, new ActionListener()
		{
			public void actionPerformed(ActionEvent ae)
			{
				y -=3;
				repaint();
				setTitle("Y: " + y + " HEIGHT: " + getHeight() +  " X: " + x + " WIDTH: " + getWidth());
				if(y < 25)
				{
					timerUp.stop();
					timerDown.start();
				}
			}
		});
		
		timerLeft = new Timer(1 , new ActionListener()
		{
			public void actionPerformed(ActionEvent goLeft)
			{
				x -= 3;
				repaint();
				if(x <= 5)
				{
					timerRight.start();
					timerLeft.stop();
				}
			}
		});
		
		timerRight = new Timer(1 , new ActionListener()
		{
			public void actionPerformed(ActionEvent goLeft)
			{
				x += 5;
				repaint();
				if(x >= getWidth() - 25)
				{
					timerRight.stop();
					timerLeft.start();
				}
			}
		});
		
		
		
		
		
		timerLeftRight = new Timer(3, new ActionListener()
		{
			public void actionPerformed(ActionEvent ok)
			{
				if(x >= 500)
				{
					goLeft();
				}
				else
				{
					goRight();
				}
				//System.out.println("Im running");
				timerLeftRight.stop();
			}
		});
		
		
	} // constructor end
	
	
	public void update(Graphics g)
    {
         paint(g);
         System.out.println("Im running");
    } 
	
	public void goLeft()
	{
		timerLeft.start();
	}
	
	public void goRight()
	{
		timerRight.start();
	}
	
	public void up()
	{
		timerUp.start();
	}
	
	public void down()
	{
		timerDown.start();
		
	}
	
	public void paint(Graphics g)
	{
		super.paint(g);
		g.setColor(Color.cyan);
		g.fillOval(x,y,20,20);
	}
	
	public static void main(String[] arhs)
	{
		new aball();
	}
	
}

class modJPanel extends JPanel
{
	public modJPanel()
	{
		this.setBackground(Color.BLUE);
		this.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "HELP THE NEWBIE"));
	}
}

BTW guys, some codes there is not really necessary like the class modJPanel.. thanks..

Your code gets this error:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at BouncingBall$1.actionPerformed(BouncingBall.java:41)
at javax.swing.Timer.fireActionPerformed(Unknown Source)

The variable at line 41 is null????

its working at my editor. Its a timer. I use timer to animate the ball. But, it flicks.

Because of timing it is possible to call a listener BEFORE the timer reference is set.
I sometimes get NPE when I start it. You need to give all the timers values before you call code that expects the variable to have a value.

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at BouncingBall$1.actionPerformed(BouncingBall.java:41)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)

Why do you set it visible and THEN move it the center? That makes the frame jump from the corner to center.

Edited 5 Years Ago by NormR1: n/a

Well... you have a repaint (); in your timer code.
Do you really want to repaint the entire screen whenever your timer(s) get executed?
Also... The first argument in a Timer declaration is the time in milliseconds.
Move your repaint (); statements in more stratigic locations.

Edited 5 Years Ago by hfx642: n/a

I would reconsider whether that many timers are needed at all.

Generally a single timer is user for animation. It updates all component locations as needed and then repaints.

Edited 5 Years Ago by Ezzaral: n/a

Actually... I would agree.
You only need one timer and decide which actions to perform inside the one handler.

but if i use only a single timer, wont it flicks at all? Coz idk how to code in single timer at the moment.

ok, so the timer or the thread is not the issue about flicking, its the repaint()? Do you want to minimize the calling of repaint? Sorry cant understand almost.

Try this and see the effect:
move ModJPanel to be an inner class and copy and rename the paint method to be paintComponent in the ModJPanel class.

oh thanks, but im not sure how to do that. Im a newbie. Do you mean:

class class1{
class innerClass{}
}

???

Yes. Move the ModJPanel class within the main class. That is so that the variables x and y are known to it. Then the new paintComponent method in ModJPanel will be able to use them

1. Too many timers. It's adding to your confusion.
2. Timing increments are too small. 1/60th of a second is a little over 16 milliseconds. No need to go smaller than that.
3. Too many repaints. Within a single timer, define your actions.
Make a decision of what code you want to run INSIDE a single actionPerformed.
THEN do a repaint() at the end of your code.

This article has been dead for over six months. Start a new discussion instead.