I am trying to change the background color of the JPanel every 3 seconds (3000 ms) when I click START button till I press STOP button.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;

class TimerBackground implements ActionListener
{
	JFrame frame; 	JPanel panel;
	JButton btnStart; 	JButton btnRed;
	JButton btnGreen; 	JButton btnBlue;
	JButton btnStop; 	Timer t;  
	Random num = new Random();  
	int r, g, b;
	TimerBackground()
	{
		r = g = b = 0;
		frame = new JFrame("Timer Background");
		panel = new JPanel();
		btnStart = new JButton("START");
		btnRed = new JButton("Red");
		btnGreen = new JButton("Green");
		btnBlue = new JButton("Blue");
		btnStop = new JButton("STOP");
		t = new Timer(3000, this);

		btnStart.addActionListener(this);	
		btnStop.addActionListener(this);
		btnRed.addActionListener(this);
		btnBlue.addActionListener(this);
		btnGreen.addActionListener(this);
		t.addActionListener(this);
	
		frame.setSize(800,600);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.setContentPane(panel);
		panel.add(btnStart);
		panel.add(btnStop);
		panel.add(btnRed);
		panel.add(btnGreen);

		t.start();
	}
	
	public void actionPerformed(ActionEvent evnt)
	{
		if(evnt.getSource() == btnRed)
		{
			panel.setBackground(new Color(255,0,0));
		}
		else if(evnt.getSource() == btnGreen)
		{
			panel.setBackground(new Color(0,255,0));
		}
		else if(evnt.getSource() == btnBlue)
		{
			panel.setBackground(new Color(0,0,255));
		}
		else if(evnt.getSource() == btnStart)
		{
			//Are The Lines Below Correct or else What Should I Write Here??
			r = num.nextInt(255);
			g = num.nextInt(255);
			b = num.nextInt(255);
			panel.setBackground(new Color(r, g, b));
		}
		else if(evnt.getSource() == btnStop)
		{
			t.stop();
		}
	}

	public static void main(String[] args)
	{
		TimerBackground timerB = new TimerBackground();
	}
}

The above code works only once on click of START button. I don't understand how to make it run every 3 seconds.

Dani AI

Generated

is right: let a Swing timer do the repeating; do not write your own loop. In your code you add yourself as the timer listener, but you never handle events coming from the timer, so nothing runs every 3 seconds. Start the timer when START is clicked, stop it on STOP, and make the timer’s listener change the color. Also avoid adding the same listener twice and do not start the timer in the constructor. See the official tutorial for the pattern. How to Use Swing Timers. (docs.oracle.com)

A minimal structure that works:

// create once
final Random rnd = new Random();
final Timer colorTimer = new Timer(3000, e -> {
    panel.setBackground(new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)));
});

// wire buttons
startButton.addActionListener(e -> { if (!colorTimer.isRunning()) colorTimer.start(); });
stopButton.addActionListener(e -> colorTimer.stop());

// optional: fire immediately on START instead of waiting 3s
colorTimer.setInitialDelay(0);

Notes:

  • The timer runs on the Swing event dispatch thread, so updating Swing components inside its listener is safe. The default is to repeat; use setRepeats(false) if you ever need a one-shot. Timer API. (docs.oracle.com)
  • Use nextInt(256) to cover the full 0..255 range for each RGB component.

If you switch to java.util.Timer/TimerTask as you mentioned later, remember those callbacks happen on a background thread. Any Swing update must be marshaled back to the EDT, for example with SwingUtilities.invokeLater(...). The Swing concurrency docs explain why this matters and how to do it safely. Concurrency in Swing. (docs.oracle.com)

And to reinforce ’s correction to : no manual loops with sleep in Swing; they block the EDT and freeze the UI. The Swing timer already handles the repetition. How to Use Swing Timers. (docs.oracle.com)

Recommended Answers

All 10 Replies

javax.swing.Timer is what you need - documentation & samples in the usual places.

Define a timer task (a "run()" method) that you want to run repeatedly. On click of the start button start a Timer that will run that task every 3000 msec. On click of the stop button stop the timer.

But I don't know how to implement it, can u give me a sample?

PLease let me know what modifications can i make to my code??

@ JamesCherrill

hard of gold :-)

Hey! Was that deliberate? Normal phrase is "heart of gold", but you wrote "hard" as in tough. difficult etc. Neat pun!
I still stand by what I said.

also implement a loop if that operation is to keep on being repeated

thank you, my fast hands and still problems wrote English words correctly, nor ...

but my reaction == this forum is long times one man show throught EU working hours, with my respect man

also implement a loop if that operation is to keep on being repeated

No no no.

The javax.swing.Timer handles the repeating. If you tell a newbie to use a loop in this context you will get a loop with a sleep in it that blocks the EDT and leads inevitably to the post that goes "why isn't by background updating?".

So, no, no loop. Just a swing Timer.

Hey I used TimerTask one as suggested by James Cherrill... Thanks.. I had to dig deep, but I found out..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.