hello!

I have run into a brick wall trying to write a traffic light program. The program must display a traffic light (so far I have tried painting it on a Graphics) and use radio buttons (red, yellow, green) to change the color of the light.

So far, I've got the radio buttons down and when I run the program it runs fine. The window displays and there are no errors. The only problem is that the traffic light painted on the Graphics is there for only a split second before the JPanel is painted over it. Any suggestions on how to keep the light visible while still having the buttons readily accessibly?

Any input would be greatly appreciated!

TrafficLight driver program

import javax.swing.*;
import java.awt.*;


public class TrafficLight
{
	public static void main (String[] args)
	{
		
		JFrame TrafficFrame = new JFrame("Traffic Light");
		TrafficFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		TrafficLightPanel tlp = new TrafficLightPanel();
		TrafficFrame.getContentPane().add(tlp.getPanel());
		
		TrafficFrame.pack();
		tlp.drawLight();			
		TrafficFrame.show();
	}
}

TrafficLightPanel class

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

public class TrafficLightPanel extends JPanel
{
	private final int width = 300, height = 500;
	private final int radius = 30;
	private JPanel primary;
	private JLabel options;
	private JRadioButton green, yellow, red;
	
	public TrafficLightPanel()
	{
		//options = new JLabel("Choose a light color");
		//options.setFont (new Font ("Helvetica", Font.BOLD, 28));
		
		red = new JRadioButton ("Red", true);
		//red.setBackground(Color.gray);
		yellow = new JRadioButton ("Yellow");
		//yellow.setBackground(Color.gray);
		green = new JRadioButton ("Green");
		//green.setBackground(Color.gray);
		
		ButtonGroup group = new ButtonGroup();
		group.add(red);
		group.add(yellow);
		group.add(green);
		
		LightListener listener = new LightListener();
		red.addActionListener(listener);
		yellow.addActionListener (listener);
		green.addActionListener (listener);
		
		primary = new JPanel();
		//primary.add(options);
		primary.add(red);
		primary.add(yellow);
		primary.add(green);
		//primary.setBackground(Color.gray);
		primary.setPreferredSize(new Dimension(width, height));

	}
	
	public void drawLight()
	{
		Graphics page = primary.getGraphics();

		page.setColor(Color.black);
		page.fillRect(40, 100, 100, 300);
		
		page.setColor(Color.red);
		page.fillOval(50, 110, 100, 300);
			
		page.setColor(Color.yellow);
		page.fillOval(50, 210, 100, 300);
			
		page.setColor(Color.green);
		page.fillOval(50, 310, 100, 300);
		
		primary.paint(page); 				
	}
	
	public JPanel getPanel()
	{
		return primary;
	}
	
	private class LightListener implements ActionListener
	{
		public void actionPerformed (ActionEvent event)
		{
			Object source = event.getSource();
			
			if (source == red)
			{
				Graphics page = primary.getGraphics();

				page.setColor(Color.black);
				page.fillRect(40, 40, 100, 300);
				
				page.setColor(Color.red);
				page.fillOval(50, 50, 80, 80);
					
				page.setColor(Color.gray);
				page.fillOval(50, 150, 80, 80);
					
				page.setColor(Color.gray);
				page.fillOval(50, 250, 80, 80);
				
				primary.paint(page);
			}
			else
				if (source == yellow)
				{
					Graphics page = primary.getGraphics();
	
					page.setColor(Color.black);
					page.fillRect(40, 40, 100, 300);
					
					page.setColor(Color.gray);
					page.fillOval(50, 50, 80, 80);
						
					page.setColor(Color.yellow);
					page.fillOval(50, 150, 80, 80);
						
					page.setColor(Color.gray);
					page.fillOval(50, 250, 80, 80);
				
					primary.paint(page);
				}
				else 
				{
					Graphics page = primary.getGraphics();
	
					page.setColor(Color.black);
					page.fillRect(40, 40, 100, 300);
					
					page.setColor(Color.gray);
					page.fillOval(50, 50, 80, 80);
						
					page.setColor(Color.gray);
					page.fillOval(50, 150, 80, 80);
						
					page.setColor(Color.green);
					page.fillOval(50, 250, 80, 80);
					
					primary.paint(page);
				}
		}
	}

	
}

Because, since you are simply painting to the graphics in an external method, rather than overriding the paintComponent method in JPanel will cause the standard "painting" of the panel to erase it. Either extend JPanel and override the paintComponent method, or have that method create an image (use BufferedImage and you can do that exactly as you are doing this now) and set that as the contents of the JPanel.

Comments
insightful and truly helpful

overriding the paintComponent(Graphics page) method did the trick. Thanks so much!

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

public class TrafficLightPanel extends JPanel
{
	private final int width = 300, height = 500;
	private final int radius = 30;
	private JPanel primary;
	private JLabel options;
	private JRadioButton green, yellow, red;
	
	public TrafficLightPanel()
	{
		options = new JLabel("Choose a light color");
		options.setFont (new Font ("Helvetica", Font.BOLD, 28));
		
		red = new JRadioButton ("Red", true);
		red.setBackground(Color.gray);
		yellow = new JRadioButton ("Yellow");
		yellow.setBackground(Color.gray);
		green = new JRadioButton ("Green");
		green.setBackground(Color.gray);
		
		ButtonGroup group = new ButtonGroup();
		group.add(red);
		group.add(yellow);
		group.add(green);
		
		LightListener listener = new LightListener();
		red.addActionListener(listener);
		yellow.addActionListener (listener);
		green.addActionListener (listener);
		
		primary = new JPanel();
		primary.add(options);
		primary.add(red);
		primary.add(yellow);
		primary.add(green);
		primary.setBackground(Color.gray);
		primary.setPreferredSize(new Dimension(width, height));

	}
	
	public JPanel getPanel()
	{
		return primary;
	}
	
	public void paintComponent(Graphics page)
	{
		page.setColor(Color.black);
		page.fillRect(40, 110, 100, 300);
		
		page.setColor(Color.red);
		page.fillOval(50, 120, 80, 80);
			
		page.setColor(Color.yellow);
		page.fillOval(50, 220, 80, 80);
			
		page.setColor(Color.green);
		page.fillOval(50, 320, 80, 80);
		
		super.paint(page);
	}
	
	
	private class LightListener implements ActionListener
	{
		public void actionPerformed (ActionEvent event)
		{
			Object source = event.getSource();
			
			if (source == red)
			{
				Graphics page = primary.getGraphics();

				page.setColor(Color.black);
				page.fillRect(40, 110, 100, 300);
				
				page.setColor(Color.red);
				page.fillOval(50, 120, 80, 80);
					
				page.setColor(Color.gray);
				page.fillOval(50, 220, 80, 80);
					
				page.setColor(Color.gray);
				page.fillOval(50, 320, 80, 80);
				
				repaint();
			}
			else
				if (source == yellow)
				{
					Graphics page = primary.getGraphics();
	
					page.setColor(Color.black);
					page.fillRect(40, 110, 100, 300);
					
					page.setColor(Color.gray);
					page.fillOval(50, 120, 80, 80);
						
					page.setColor(Color.yellow);
					page.fillOval(50, 220, 80, 80);
						
					page.setColor(Color.gray);
					page.fillOval(50, 320, 80, 80);
				
					repaint();
				}
				else 
				{
					Graphics page = primary.getGraphics();
	
					page.setColor(Color.black);
					page.fillRect(40, 110, 100, 300);
					
					page.setColor(Color.gray);
					page.fillOval(50, 120, 80, 80);
						
					page.setColor(Color.gray);
					page.fillOval(50, 220, 80, 80);
						
					page.setColor(Color.green);
					page.fillOval(50, 320, 80, 80);
					
					repaint();
				}
		}
	}

	
}
import javax.swing.*;
import java.awt.*;


public class TrafficLight
{
	public static void main (String[] args)
	{
		
		JFrame TrafficFrame = new JFrame("Traffic Light");
		TrafficFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		TrafficLightPanel tlp = new TrafficLightPanel();
		TrafficFrame.getContentPane().add(tlp.getPanel());
		
		TrafficFrame.pack();			
		TrafficFrame.show();
	}
}
This question has already been answered. Start a new discussion instead.