2013-01-17 156 views
5

我正在使用JProgressBar组件以及Nimbus UI默认值。问题是,当我想手动更改每个进度条的Bar颜色时,我通过设置JProgressBar.setUI()函数使用BasicProgressBarUI。这使得更麻烦,因为我想只改变条的颜色,似乎我松开jprogressbar的默认外观(Border,backgroundcolor消失)。JProgressBar动态更改条形颜色

因此,当代码初始化时,我可以设置Nimbus ProgressBar的UIDefaults。有用。

但我想动态改变每个进度条的颜色条。

是否有任何其他方式更改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(); 
    } 
} 
+1

为更好地帮助更快张贴[SSCCE(http://sscce.org/),短,可运行,编译,否则要搜索,谷歌可以返回 – mKorbel

+2

参见[这] (http://stackoverflow.com/questions/7174420/change-colors-for-jprogressbar-with-nimbus)类似的问题/答案,它显示了如何使用'UIDefaults'和'putClientProperty'来改变一个'JProgressBar'颜色 –

+0

目前的问题是当我使用setForeground(Color.GREEN)更改条形颜色时;它会更改SelectionBackground颜色。看来,setBackgroundColor(Color.RED);命令不会执行任何操作。 – mbasol

回答

4

Kelopatra +1为第一。

这里是我提出一个例子:

的JProgressBar的颜色initaily经由设置:

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); 

在50%进展的颜色将改变为RED:

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);       
} 

测试.java:

enter image description here

enter image description here

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); 
    } 
} 
+1

+1根据值动态改变颜色,很好的触摸:-) – kleopatra

+0

@David Kroukamp这是否意味着我可以重写JProgressBar的setBackground和setForeground方法并正确应用UI默认值? – mbasol

+0

@mbasol是的我看不出有什么理由不能做 –

3

Nimbus支持每个组件的蒙皮,比如已经在其他QA中得到了回答。适用于JProgressBar的“酒吧”,这意味着与像自定义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); 

的mimimal(难看),画家会是这样的:

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; 
    } 

} 

为了使它在视觉上赏心悦目,看看ProgressBarPainter:它是封装私有的,所以除了了解如何实现其渐变/路径绘画并在自定义实现中执行相同操作之外,您无法做其他事情。

+1

+1不要忘记“ProgressBar [Enabled + Finished] .foregroundPainter”,或者它将在100%的竞争中恢复原始状态 –

+1

@DavidKroukamp好的捕捉 - 谢谢你的领导:-) – kleopatra