2013-01-17 204 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