Your while loop is stopping the repaint manager from ever getting around to changing the colors.
You need to, some how, execute the request in the background, something like this
public class TestLabel extends JLabel {
private Timer timer;
private int r = 0;
private int g = 155;
private int b = 12;
public TestLabel() {
setText("Hello world");
setOpaque(true);
timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("tick");
r = (r + 1) % 255;
g = (g + 1) % 255;
b = (b + 1) % 255;
Color color = new Color(r, g, b);
setBackground(color);
System.out.println(color);
if (r == 0 && b == 0 && g == 0) {
r = 0;
g = 155;
b = 12;
}
invalidate();
revalidate();
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
}
You might like to read up on
UPDATED with Extended Example
public class TestLabel extends JLabel {
private Timer timer;
private Object[][] colors = {{"Black", Color.BLACK},
{"Blue", Color.BLUE},
{"Cyan", Color.CYAN},
{"Dark Gray", Color.DARK_GRAY},
{"Gray", Color.GRAY},
{"Green", Color.GREEN},
{"Light Gary", Color.LIGHT_GRAY},
{"Mangenta", Color.MAGENTA},
{"Orange", Color.ORANGE},
{"Pink", Color.PINK},
{"Red", Color.RED},
{"White", Color.WHITE},
{"Yellow", Color.YELLOW}};
public TestLabel() {
setText("Hello world");
setOpaque(true);
timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("tick");
int index = (int) Math.round((colors.length - 1) * Math.random());
Object[] group = colors[index];
setBackground((Color)group[1]);
setText((String)group[0]);
}
});
timer.setInitialDelay(0);
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
}