Solved

JProgressBar Changing Bar Color dynamically

Posted on 2013-01-16
11
2,092 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Problem to error 4 47
difference of if loops 23 43
MySQL  on Tomcat 8 30
servlet filter example 37 46
Preface This is the third article about the EE Collaborative Login Project. A Better Website Login System (http://www.experts-exchange.com/A_2902.html) introduces the Login System and shows how to implement a login page. The EE Collaborative Logi…
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.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…

863 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

23 Experts available now in Live!

Get 1:1 Help Now