Solved

JProgressBar Changing Bar Color dynamically

Posted on 2013-01-16
11
2,054 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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Problem to echo 6 56
Element alignment and word wrapping 9 28
Re-position the objects 7 52
Java Timer (static) 9 18
SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…

747 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

8 Experts available now in Live!

Get 1:1 Help Now