Search code examples
javaswingjprogressbarnimbusuimanager

JProgressBar Changing Bar Color dynamically


I am using JProgressBar component along with the Nimbus UI Defaults. The problem is that When I want to manually change each progressbar's Bar color, I use BasicProgressBarUI by setting JProgressBar.setUI() function. This makes more trouble because I would like to just change the bar color and it seems that I loose the default look of the jprogressbar (Border, backgroundcolor dissappears).

So I can set UIDefaults of Nimbus ProgressBar when the code initializes. It works.

But I want to change each progressbar's bar color dynamically.

Is there any other way of changing Bar color of JProgressBar?

public class ProgressGenerator extends JFrame {

    protected int minValue = 0;
    protected int maxValue = 100;
    protected int counter = 0;
    protected JProgressBar progressBar;

    public ProgressGenerator() {
        super("JProgressBar Demo");
        setSize(300, 100);

        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (InstantiationException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (UnsupportedLookAndFeelException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        progressBar = new JProgressBar();
        progressBar.setMinimum(minValue);
        progressBar.setMaximum(maxValue);
        progressBar.setStringPainted(true);

        progressBar.setForeground(Color.GREEN);

        JButton start = new JButton("Start");
        start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Thread runner = new Thread() {
                    public void run() {
                        counter = minValue;
                        while (counter <= maxValue) {
                            Runnable runme = new Runnable() {
                                public void run() {
                                    progressBar.setValue(counter);
                                }
                            };
                            SwingUtilities.invokeLater(runme);
                            counter++;
                            try {
                                Thread.sleep(100);
                            } catch (Exception ex) {
                            }
                        }
                    }
                };
                runner.start();
            }
        });
        getContentPane().add(progressBar, BorderLayout.CENTER);
        getContentPane().add(start, BorderLayout.WEST);
        WindowListener wndCloser = new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        };
        addWindowListener(wndCloser);
        setVisible(true);
    }

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

Solution

  • +1 to Kelopatra for being first.

    Here is an example I made:

    The JProgressBar color is initaily set via:

    UIDefaults defaults = new UIDefaults();
    defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.GREEN));
    defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.GREEN));
    
    progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
    progressBar.putClientProperty("Nimbus.Overrides", defaults);
    

    On 50% progress the color will be changed to RED:

    if (progressBar.getValue() == 50) {//change color on 50%
       UIDefaults defaults = new UIDefaults();
       defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));
       defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));
       progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
       progressBar.putClientProperty("Nimbus.Overrides", defaults);                          
    }
    

    Test.java:

    enter image description here

    enter image description here

    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.event.*;
    import java.beans.*;
    import javax.swing.*;
    
    public class Test {
    
        public static void createAndShowGUI() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            final JProgressBar progressBar = new JProgressBar();
            progressBar.setStringPainted(true);
            progressBar.setValue(0);
            progressBar.setBorderPainted(false);
    
            JButton startButton = new JButton("Start");
    
            startButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    UIDefaults defaults = new UIDefaults();
                    defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.GREEN));
                    defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.GREEN));
    
                    progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
                    progressBar.putClientProperty("Nimbus.Overrides", defaults);
    
                    SwingWorker worker = new SwingWorker() {
                        int current = 0, lengthOfTask = 100;
    
                        @Override
                        public Void doInBackground() {
                            while (current <= lengthOfTask && !isCancelled()) {
    
                                try { // dummy task
                                    Thread.sleep(50);
                                } catch (InterruptedException ie) {
                                }
    
                                setProgress(100 * current / lengthOfTask);
                                current++;
                            }
                            return null;
                        }
                    };
                    worker.addPropertyChangeListener(new PropertyChangeListener() {
                        @Override
                        public void propertyChange(PropertyChangeEvent pce) {
    
                            String strPropertyName = pce.getPropertyName();
                            if ("progress".equals(strPropertyName)) {
                                int progress = (Integer) pce.getNewValue();
                                progressBar.setValue(progress);
    
                                if (progressBar.getValue() == 50) {//change color on 50%
                                    UIDefaults defaults = new UIDefaults();
                                    defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));
                                    defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));
    
                                    progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
                                    progressBar.putClientProperty("Nimbus.Overrides", defaults);
                                }
    
                            }
                        }
                    });
                    worker.execute();
                }
            });
    
            JPanel holder = new JPanel();
            holder.add(progressBar);
            holder.add(startButton);
    
            frame.add(holder);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
                    createAndShowGUI();
                }
            });
        }
    }
    
    class MyPainter implements Painter<JProgressBar> {
    
        private final Color color;
    
        public MyPainter(Color c1) {
            this.color = c1;
        }
        @Override
        public void paint(Graphics2D gd, JProgressBar t, int width, int height) {
            gd.setColor(color);
            gd.fillRect(0, 0, width, height);
        }
    }