Search code examples
javaswingawtthread-sleepsetbackground

Animate bg color with hsb model Java


I'm fairly new to java, so i don't think I have this fairly close to right, but I can seem to find any other help with this. Basically, I'm trying to animate a jPanel's background color so that it's hue (I'm using an hsb color model) changes. sort of like this: https://kahoot.it/#/ notice how the color kinda floats from one to another. Here is my code that I have so far:

public void animate(){


    for(float i=.001f;i<1f;i+=.001f){


            jPanel1.setBackground(Color.getHSBColor(i, .53f, .97f));
            try{
                Thread.sleep(5L);
            }catch(InterruptedException ex){

            }
        System.out.println(i);

    }

}

now i know this probably isn't right, but the loop works fine, the only problem is that the jPanel doesn't "update" until the loop is finished. Sorry all for being a huge noob at stuff like this, and thanks for any responses


Solution

  • The problem is that you are blocking the event dispatch thread, so no drawing can happen. Use a swing Timer instead of sleeping. A running example of changing HSB colors:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class ColorCycle {
        private static class ColorPanel extends JPanel {
            private final float stepSize;
            private final Timer timer;
            private int index;
    
            ColorPanel(final int steps, int fps) {
                stepSize = 1f / steps;
                timer = new Timer(1000 / fps, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        index++;
                        if (index > steps) {
                            index = 0;
                        }
                        repaint();
                    }
                });
            }
    
            void start() {
                timer.start();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(100, 100);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.getHSBColor(index * stepSize, 1f,  1f));
                g.fillRect(0, 0, getWidth(), getHeight());
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame("Colors");
                    ColorPanel panel = new ColorPanel(300, 20);
                    frame.getContentPane().add(panel);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLocationByPlatform(true);
                    frame.pack();
                    frame.setVisible(true);
                    panel.start();  
                }
            });
        }
    }