Solved

JProgressBar Changing Bar Color dynamically

Posted on 2013-01-16
11
2,247 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
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 
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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

617 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