我正在尝试创建一个使用JLayer类的自定义JProgressBar,以便根据情况la this solution进行不同的着色。问题是我想把它包装成某种类型的JComponent,因为它使它更易于管理。我会把它作为一个自定义的JLayer公开,但那个类是密封的,所以什么也没做。
我试过让它成为一个JComponent,但屏幕上没有画出任何东西(可能是因为我不知道如何制作一个包含其中内部组件的自定义JComponent?)。我已经尝试了一个JFrame,但是调整大小都是错误的,可能是因为进度条使用的是我制作的JFrame的布局管理器而不是包含JFrame的布局管理器。我已经尝试了绘制的JProgressBar,但是在构造函数之后没有额外的方法调用,我无法返回JLayer并保留正确的层次结构,这看起来并不优雅。
这是我的示例代码,主要基于我上面链接的问题中的代码:
public class Test {
public JComponent makeUI() {
final BoundedRangeModel model = new DefaultBoundedRangeModel();
model.setValue(20);
final JPanel p = new JPanel(new GridLayout(4, 1, 12, 12));
p.setBorder(BorderFactory.createEmptyBorder(24,24,24,24));
// This does not draw
final ColorProgressBar pb4 = new ColorProgressBar(model);
p.add(pb4);
JPanel panel = new JPanel(new BorderLayout());
panel.add(p, BorderLayout.NORTH);
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new Test().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class ColorProgressBar extends JComponent {
private static final long serialVersionUID = -1265489165072929352L;
private BlockedColorLayerUI colorUI = new BlockedColorLayerUI();
private JLayer<JProgressBar> layer;
private JProgressBar bar;
private PropertyChangeSupport supporter = new PropertyChangeSupport(new WeakReference<ColorProgressBar>(this));
public ColorProgressBar(BoundedRangeModel model) {
bar = new JProgressBar(model);
layer = new JLayer<JProgressBar>(bar, colorUI);
this.add(layer);
}
public Color getColor() {
if (colorUI == null)
return null;
return colorUI.color;
}
public void setColor(Color color) {
Color oldColor = colorUI.color;
colorUI.color = color;
supporter.firePropertyChange("color", oldColor, color);
}
@Override
public void paintComponents(Graphics g) {
layer.paintComponents(g);
}
class BlockedColorLayerUI extends LayerUI<JProgressBar> {
public Color color = null;
private BufferedImage bi;
private int prevw = -1;
private int prevh = -1;
@Override public void paint(Graphics g, JComponent c) {
if(color != null) {
JLayer<?> jlayer = (JLayer<?>)c;
JProgressBar progress = (JProgressBar)jlayer.getView();
int w = progress.getSize().width;
int h = progress.getSize().height;
if(bi==null || w!=prevw || h!=prevh) {
bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
}
prevw = w;
prevh = h;
Graphics2D g2 = bi.createGraphics();
super.paint(g2, c);
g2.dispose();
Image image = c.createImage(
new FilteredImageSource(bi.getSource(),
new ColorFilter(color)));
g.drawImage(image, 0, 0, c);
} else {
super.paint(g, c);
}
}
}
class ColorFilter extends RGBImageFilter {
Color color;
public ColorFilter(Color color) {
this.color = color;
}
@Override public int filterRGB(int x, int y, int argb) {
int r = (int)((argb >> 16) & 0xff);
int g = (int)((argb >> 8) & 0xff);
int b = (int)((argb ) & 0xff);
return (argb & color.getRGB()) | (g<<16) | (r<<8) | (b);
}
}
}
任何人都知道我哪里出错了?谢谢!
编辑:我已经略微修改了示例并对其进行了修改以更好地表达我的问题。对不起,感到困惑。
答案 0 :(得分:1)
您可能需要致电super(model);
和p.add(pb4.layer);
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.beans.*;
import java.lang.ref.WeakReference;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class Test2 {
public JComponent makeUI() {
final BoundedRangeModel model = new DefaultBoundedRangeModel();
final JPanel p = new JPanel(new GridLayout(4, 1, 12, 12));
p.setBorder(BorderFactory.createEmptyBorder(24,24,24,24));
final JProgressBar pb1 = new JProgressBar(model);
pb1.setStringPainted(true);
p.add(pb1);
final JProgressBar pb2 = new JProgressBar(model);
pb2.setStringPainted(true);
p.add(pb2);
p.add(new JProgressBar(model));
final ColorProgressBar pb4 = new ColorProgressBar(model);
p.add(pb4.layer);
JPanel box = new JPanel();
box.add(new JButton(new AbstractAction("+10") {
private int i = 0;
@Override public void actionPerformed(ActionEvent e) {
model.setValue(i = (i>=100) ? 0 : i + 10);
}
}));
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa511486.aspx
box.add(new JCheckBox(new AbstractAction(
"<html>Turn the progress bar red<br />"+
" when there is a user recoverable condition<br />"+
" that prevents making further progress.") {
@Override public void actionPerformed(ActionEvent e) {
boolean b = ((JCheckBox)e.getSource()).isSelected();
pb2.setForeground(b? new Color(255,0,0,100) : new Color(255,255,0,100));
if (b)
pb4.setColor(Color.RED);
else
pb4.setColor(Color.YELLOW);
p.repaint();
}
}));
JPanel panel = new JPanel(new BorderLayout());
panel.add(p, BorderLayout.NORTH);
panel.add(box, BorderLayout.SOUTH);
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new Test2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class ColorProgressBar extends JProgressBar {
private static final long serialVersionUID = -1265489165072929352L;
private BlockedColorLayerUI colorUI = new BlockedColorLayerUI();
public JLayer<JProgressBar> layer;
private PropertyChangeSupport supporter = new PropertyChangeSupport(new WeakReference<ColorProgressBar>(this));
public ColorProgressBar(BoundedRangeModel model) {
super(model);
layer = new JLayer<JProgressBar>(this, colorUI);
}
public Color getColor() {
if (colorUI == null)
return null;
return colorUI.color;
}
public void setColor(Color color) {
Color oldColor = colorUI.color;
colorUI.color = color;
supporter.firePropertyChange("color", oldColor, color);
}
// @Override
// public void paintComponents(Graphics g) {
// layer.paintComponents(g);
// }
class BlockedColorLayerUI extends LayerUI<JProgressBar> {
public Color color = null;
private BufferedImage bi;
private int prevw = -1;
private int prevh = -1;
@Override public void paint(Graphics g, JComponent c) {
if(color != null) {
JLayer<?> jlayer = (JLayer<?>)c;
JProgressBar progress = (JProgressBar)jlayer.getView();
int w = progress.getSize().width;
int h = progress.getSize().height;
if(bi==null || w!=prevw || h!=prevh) {
bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
}
prevw = w;
prevh = h;
Graphics2D g2 = bi.createGraphics();
super.paint(g2, c);
g2.dispose();
Image image = c.createImage(
new FilteredImageSource(bi.getSource(),
new ColorFilter(color)));
g.drawImage(image, 0, 0, c);
} else {
super.paint(g, c);
}
}
}
class ColorFilter extends RGBImageFilter {
Color color;
public ColorFilter(Color color) {
this.color = color;
}
@Override public int filterRGB(int x, int y, int argb) {
int r = (int)((argb >> 16) & 0xff);
int g = (int)((argb >> 8) & 0xff);
int b = (int)((argb ) & 0xff);
return (argb & color.getRGB()) | (g<<16) | (r<<8) | (b);
}
}
}