java JProgressBar 动态更改条形颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14373999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JProgressBar Changing Bar Color dynamically
提问by mbasol
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).
我正在使用JProgressBar
组件和 Nimbus UI 默认值。问题是当我想手动更改每个进度条的 Bar 颜色时,我使用BasicProgressBarUI
了设置JProgressBar.setUI()
功能。这会带来更多麻烦,因为我只想更改条形颜色,而且似乎我失去了 jprogressbar 的默认外观(边框、背景色消失)。
So I can set UIDefaults
of Nimbus ProgressBar when the code initializes. It works.
所以我可以UIDefaults
在代码初始化时设置Nimbus ProgressBar。有用。
But I want to change each progressbar's bar color dynamically.
但我想动态更改每个进度条的栏颜色。
Is there any other way of changing Bar color of JProgressBar
?
有没有其他方法可以改变 Bar 的颜色JProgressBar
?
public class ProgressGenerator extends JFrame {
protected int minValue = 0;
protected int maxValue = 100;
protected int counter = 0;
protected JProgressBar progressBar;
public ProgressGenerator() {
super("JProgressBar Demo");
setSize(300, 100);
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InstantiationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (UnsupportedLookAndFeelException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
progressBar = new JProgressBar();
progressBar.setMinimum(minValue);
progressBar.setMaximum(maxValue);
progressBar.setStringPainted(true);
progressBar.setForeground(Color.GREEN);
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 ProgressGenerator();
}
}
采纳答案by David Kroukamp
+1 to Kelopatra for being first.
+1 凯洛帕特拉是第一。
Here is an example I made:
这是我做的一个例子:
The JProgressBar color is initaily set via:
JProgressBar 颜色最初是通过以下方式设置的:
UIDefaults defaults = new UIDefaults();
defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.GREEN));
defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.GREEN));
progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
progressBar.putClientProperty("Nimbus.Overrides", defaults);
On 50% progress the color will be changed to RED:
进度达到 50% 时,颜色将更改为红色:
if (progressBar.getValue() == 50) {//change color on 50%
UIDefaults defaults = new UIDefaults();
defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));
defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));
progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
progressBar.putClientProperty("Nimbus.Overrides", defaults);
}
Test.java:
测试.java:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
public class Test {
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);
progressBar.setBorderPainted(false);
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 MyPainter(Color.GREEN));
defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(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 MyPainter(Color.RED));
defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(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 MyPainter implements Painter<JProgressBar> {
private final Color color;
public MyPainter(Color c1) {
this.color = c1;
}
@Override
public void paint(Graphics2D gd, JProgressBar t, int width, int height) {
gd.setColor(color);
gd.fillRect(0, 0, width, height);
}
}
回答by kleopatra
Nimbus supports per-component skinning, such as already answered in the other QA. Applied to a JProgressBar "bar" that means configuring the instance with a custom foregroundPainter like:
Nimbus 支持每个组件的皮肤,例如在其他 QA 中已经回答。应用于 JProgressBar “bar”,这意味着使用自定义 foregroundPainter 配置实例,例如:
progressBar = new JProgressBar();
UIDefaults defaults = new UIDefaults();
Painter painter = new MyPainter(Color.GREEN);
defaults.put("ProgressBar[Enabled].foregroundPainter", painter);
defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", painter);
progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
progressBar.putClientProperty("Nimbus.Overrides", defaults);
The mimimal (ugly looking) painter would be something like:
最小的(丑陋的)画家应该是这样的:
public static class MyPainter extends AbstractRegionPainter {
private Color fillColor;
public MyPainter(Color color) {
// as a slight visual improvement, make the color transparent
// to at least see the background gradient
// the default progressBarPainter does it as well (plus a bit more)
fillColor = new Color(
color.getRed(), color.getGreen(), color.getBlue(), 156);
}
@Override
protected void doPaint(Graphics2D g, JComponent c, int width,
int height, Object[] extendedCacheKeys) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, width, height);
}
@Override
protected PaintContext getPaintContext() {
return null;
}
}
To make it visually pleasing, have a look into ProgressBarPainter: it's package private so you can't do much other than understand how it achieves its gradients/path painting and do the same in a custom implementation.
为了使它在视觉上令人愉悦,请查看 ProgressBarPainter:它是私有包,因此除了了解它如何实现渐变/路径绘制并在自定义实现中执行相同操作外,您无能为力。