Solved

JProgressBar Changing Bar Color dynamically

Posted on 2013-01-16
11
2,191 Views
Last Modified: 2013-01-18
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?
0
Comment
Question by:benchpresser
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +1
11 Comments
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 38789104
I recommended to the admins to move this into the Java zone so you can get someone who knows Java to look at it.
While I'm here though, can you not use the setUI function to set all the other elements too? So you set the color and the border and everything else. Just set everything else to whatever the default was.
0
 
LVL 37

Expert Comment

by:zzynx
ID: 38792071
Does this code helps you?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class JProgressBarDemo extends JFrame {
    protected int minValue = 0;
    protected int maxValue = 100;
    protected int counter = 0;
    protected JProgressBar progressBar;
    public JProgressBarDemo() {
        super("JProgressBar Demo");
        setSize(300, 100);
        UIManager.put("ProgressBar.background", Color.BLACK); //colour of the background
        UIManager.put("ProgressBar.foreground", Color.RED); //colour of progress bar
        UIManager.put("ProgressBar.selectionBackground",Color.YELLOW); //colour of percentage counter on black background
        UIManager.put("ProgressBar.selectionForeground",Color.BLUE); //colour of precentage counter on red background
        progressBar = new JProgressBar();
        progressBar.setMinimum(minValue);
        progressBar.setMaximum(maxValue);
        progressBar.setStringPainted(true);
        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 JProgressBarDemo();
    }
}

Open in new window

0
 

Author Comment

by:benchpresser
ID: 38792246
Well, I have found Solution but The bar color exceeds the border So I haven't figured out how  the bar not to exceed the progressbar border.

Withing Painter class  g.fillRect(0, 0, width, height); Draws the bar with border but The bar color exceeds the border which I dont want.

The code looks like:

public class TestApp {

    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);

        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 FillPainter(Color.GREEN));
                defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new FillPainter(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 FillPainter(Color.RED));
                                defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new FillPainter(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 FillPainter implements Painter<JProgressBar> {

    private final Color c1;

    public FillPainter(Color c1) {
        this.c1 = c1;
    }

    @Override
    public void paint(Graphics2D g, JProgressBar object, int width, int height) {
        g.setColor(c1);
        g.fillRect(0, 0, width, height);
    }
}

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 16

Expert Comment

by:krakatoa
ID: 38792258
Waaa ! zzynx - what an actionPerformed routine! Can you explain (for my edification at least), how the runme Runnable fits in? It's pretty cool looking. - A new Runnable for each %-age point?
0
 
LVL 37

Expert Comment

by:zzynx
ID: 38792294
First, it's not code I wrote myself. I just found it myself ;-)

About that Runnable:

Why and when do you write

        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        performAction();
                    }
                }
        );

instead of just:

       performAction();

The API docs say this about invokeLater():

Causes doRun.run() to be executed asynchronously on the AWT event dispatching thread. This will happen after all pending AWT events have been processed. This method should be used when an application thread needs to update the GUI.

Good background info @ http://www.javamex.com/tutorials/threads/invokelater.shtml
0
 

Author Comment

by:benchpresser
ID: 38792360
Well, I would like to show that I want to change the bar color of progressbar dynamically,

My target is to re-draw the progressbar component properly like nimbus version. Difference between nimbus and this version should only the bar color will be changed from orange to different color.

So I managed to change the bar color but the bar exceeds the actual progressbar border.
0
 
LVL 16

Expert Comment

by:krakatoa
ID: 38792370
Yes, zzynx - you're right - the EDT of course - just realised.
0
 
LVL 37

Accepted Solution

by:
zzynx earned 500 total points
ID: 38792720
@benchpresser
>>... but the bar exceeds the actual progressbar border.
It's a matter of playing with those coordinates.
Replacing
g.fillRect(0, 0, width, height);

Open in new window

by e.g.
g.fillRect(3, 3, width-6, height-6);

Open in new window

works for me.
0
 
LVL 16

Expert Comment

by:krakatoa
ID: 38793405
I was also going to say that this (which I can be rightly ashamed of ( ;) ), might give you some other ideas at least :

import javax.swing.JProgressBar;
import javax.swing.JFrame;
import java.awt.Dimension;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

class ProgBar extends JFrame {

static ProgBar p;
static Runnable pb;
static JProgressBar jpb ;
static int r,g,b,counter=0;

	static class RunBar implements Runnable, ActionListener{

		public void actionPerformed(ActionEvent a){
			try{
			 r = (int) (Math.random() * counter*10);
			 g = (int) (Math.random() * counter*10/2);
			 b = (int) (Math.random() * counter*10/3);
			jpb.setForeground(new java.awt.Color(r,g,b));
			}catch(Exception exc){}

			


		}

		public void run(){

		    	while (counter <= 100) {
                           	                              		 	
                                   		 jpb.setValue(counter);                  			
                           			counter++;
                           		 	try {Thread.sleep(200); 
				}catch (Exception ex) {continue;}
                                      	}
			
                        	     

		}
	}


 public static void main(String[] args){

	
	p = new ProgBar();
	p.setLayout(new BorderLayout());
	jpb = new JProgressBar();
	JButton jb = new JButton("Change Color");
	
	pb = new Thread(new RunBar());

	jb.addActionListener(new RunBar());

	p.getContentPane().add(jpb, BorderLayout.NORTH);
	p.getContentPane().add(jb, BorderLayout.SOUTH);
	
	p.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	p.setSize(new Dimension(80,120));
	
	p.setVisible(true);

	pb.run();

	
 }

}

Open in new window

0
 
LVL 37

Expert Comment

by:zzynx
ID: 38793419
Thanx 4 axxepting
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
ejb example issues 3 89
php mysql check email already in database. (second check) 7 145
wild fly 8 startup error 2 82
Java import explained 4 49
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Suggested Courses

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question