tussya tussya - 6 months ago 10
Java Question

How to make shapes "blink" or change colors in Java?

I'm trying to learn how to draw a shape, and be able to a) draw it, "freeze" the process, draw it in the color of the background, and then re-draw it in the original color and b) draw a shape and change its color. All I have so far is (for blinking):

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

public class Carlight extends JPanel{
Thread th=new Thread();
public void paintComponent (Graphics g){
super.paintComponents(g);
g.setColor(Color.yellow);
g.fillOval(25, 25, 10, 10);
try{
th.sleep(10);
}catch(InterruptedException e){}
repaint();
g.setColor(Color.yellow);
g.fillOval(25, 25, 10, 10);
try{
th.sleep(10);
}catch(InterruptedException e){}
repaint();
g.setColor(Color.yellow);
g.fillOval(25, 25, 10, 10);
}
public Carlight(){
JFrame frame=new JFrame();
frame.setTitle("Carlights");
frame.add(this);
frame.setBackground(Color.black);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100,150);
frame.setVisible(true);
}
public static void main(String[] args){
new Carlight();
}
}


How do I make this code work and how do I get a shape to change color?

Answer
import java.awt.Color;
import java.awt.Graphics;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class carlight extends JPanel
{
    private Color lastColor = Color.YELLOW;
    // For telling the panel to be repainted at regular intervals
    ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponents(g);
        if(lastColor.equals(Color.YELLOW))
        {
            lastColor = Color.GREEN;
        }
        else
        {
            lastColor = Color.YELLOW;
        }
        g.setColor(lastColor);
        g.fillOval(25, 25, 10, 10);
    }

    public carlight()
    {
        JFrame frame = new JFrame();
        frame.setTitle("Carlights");
        frame.add(this);
        frame.setBackground(Color.black);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(100, 150);
        frame.setVisible(true);
        service.scheduleAtFixedRate(new Runnable()
        {
            public void run()
            {
                repaint();
            }
        }, 0, 1, TimeUnit.SECONDS);
    }

    public static void main(String[] args)
    {
        new carlight();
    }
}

Ok,

  • Don't put sleep calls during a paintComponent call. It means you are forcing the UI to hang/stall. This is very bad.
  • I have created a ScheduledExecutorService for regularly calling the repaint method.
  • The paint method changes the color of the lastColor. Most of the time you would be looking at some sort of model to find out of the state of it to choose which color you should be using.
  • If the problem is you aren't meant to change the color, but instead it is an off/on situation, you should have a boolean representing state and only draw the circle if it is on.