Search code examples
javaswingtimerjpaneltimertask

Moving JPanels using TimerTask


So I have set up a Java GUI like the one pictured below (apologies for horribly painted recreation):

Layout for Java GUI

Target GUI

All of the JPanels are equal size (not shown well in the drawing). What I'm trying to do is make it so that when I am doing something with the progress bars (I.E reading some text files in), the JPanels will cycle through. As in the red one will go to the bottom, the orange one will go to the top, and thus keep going in this cycle. I'd like them to change every half second and wait 2 seconds after the program is open to start moving. I'd also like them to stop when one of the progress bars reaches 100%.

After doing some reading I think the Java TimerTask class would be a good fit for this, but I have no experience with it and am not really sure how I would go about doing something like this with it.

Any hints or ideas at how to go about this would be greatly appreciated!


Solution

  • It would be far simpler to keep a model of colors (and text, if 'Red JPanel' is part of what the user sees) & simply change the BG colors of the existing panels appropriate to a counter used as an index to an array of those color(/text) combos.

    As mentioned by @MadProgrammer, A Swing Timer would be more appropriate, as the Swing timer ensures updates are made on the EDT. Or rather two timers. The 1st would be a single shot timer to delay two seconds. The 2nd would cycle the colors.

    Like this (adjust colors and numbers to need):

    enter image description here

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    
    public class ColorCycler {
    
        private JComponent ui = null;
        Color[] colors = {
            Color.RED,
            Color.ORANGE,
            Color.YELLOW,
            Color.GREEN,
            Color.CYAN.darker(),
            Color.MAGENTA.darker(),
            Color.MAGENTA.darker().darker()
        };
        int counter = 0;
        JPanel[] panels = new JPanel[colors.length];
    
        ColorCycler() {
            initUI();
        }
    
        public void initUI() {
            if (ui!=null) return;
    
            ui = new JPanel(new BorderLayout(4,4));
            ui.setBorder(new EmptyBorder(4,4,4,4));
            ui.setBackground(Color.CYAN);
    
            ui.add(new JLabel(
                    "Clock", SwingConstants.CENTER), BorderLayout.PAGE_START);
            ui.add(new JLabel(
                    "Progress Bars", SwingConstants.CENTER), BorderLayout.PAGE_END);
    
            JPanel colorPanel = new JPanel(new GridLayout(0, 1));
            Border border = new EmptyBorder(new Insets(10, 200, 10, 200));
            for (int ii=0; ii<colors.length; ii++) {
                JPanel p = new JPanel();
                p.setBorder(border);
                panels[ii] = p;
                colorPanel.add(p);
            }
            ui.add(colorPanel, BorderLayout.CENTER);
    
            ActionListener colorListener = new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    counter++;
                    setColors();
                }
            };
            final Timer colorCycleTimer = new Timer(50, colorListener);
    
            ActionListener delayListener = new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    colorCycleTimer.start();
                }
            };
            Timer delayTimer = new Timer(2000, delayListener);
            delayTimer.setRepeats(false);
            delayTimer.start();
    
            setColors();
        }
    
        private void setColors() {
            for (int ii=0; ii<colors.length; ii++) {
                panels[(counter+ii)%colors.length].setBackground(colors[ii]);
            }
        }
    
        public JComponent getUI() {
            return ui;
        }
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception useDefault) {
                    }
                    ColorCycler o = new ColorCycler();
    
                    JFrame f = new JFrame(o.getClass().getSimpleName());
                    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    f.setLocationByPlatform(true);
    
                    f.setContentPane(o.getUI());
                    f.pack();
                    f.setMinimumSize(f.getSize());
    
                    f.setVisible(true);
                }
            };
            SwingUtilities.invokeLater(r);
        }
    }