Solved

JProgressBar Changing Bar Color dynamically

Posted on 2013-01-16
11
2,110 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
  • 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
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
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

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
eclipse shortcuts 9 54
map related example 6 47
even odd program using while loop 3 40
sql import cannot be resolved jsp 3 17
The purpose of this article is to demonstrate how we can use conditional statements using Python.
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

813 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now