2013-01-17 30 views
5

Używam komponentu JProgressBar wraz z ustawieniami domyślnymi interfejsu Nimbus. Problem polega na tym, że gdy chcę ręcznie zmienić kolory paska każdego paska postępu, używam funkcji BasicProgressBarUI, ustawiając funkcję JProgressBar.setUI(). To sprawia więcej problemów, ponieważ chciałbym po prostu zmienić kolor paska i wydaje mi się, że tracę domyślny wygląd paska jprogress (granica, kolor tła znika).JProgressBar Dynamiczne zmienianie koloru prętów

Dzięki temu mogę ustawić UIDefaults programu Nimbus ProgressBar podczas inicjowania kodu. To działa.

Ale chcę dynamicznie zmieniać kolory paska każdego paska postępu.

Czy istnieje inny sposób zmiany baru koloru 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

dla lepszej pomocy prędzej POST [SSCCE] (http://sscce.org/), krótki, runnable, compilable, w przeciwnym razie trzeba szukać, Google może powróci że – mKorbel

+2

See [to] (http://stackoverflow.com/questions/7174420/change-colors-for-jprogressbar-with-nimbus) podobne pytanie/odpowiedź, które pokazuje, jak używać 'UIDefaults' i' putClientProperty' aby zmienić pojedynczy kolor 'JProgressBar' –

+0

Obecny problem dotyczy zmiany koloru paska za pomocą setForeground (Color.GREEN); zmienia kolor SelectionBackground. I wydaje się, że setBackgroundColor (Color.RED); polecenie nic nie robi. – mbasol

Odpowiedz

4

+1 do Kelopatry za bycie pierwszym.

Oto przykład zrobiłem:

Kolor JProgressBar jest initaily ustawić poprzez:

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

na 50% postępu kolor zostanie zmieniony na czerwono:

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

testowym .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 za dynamiczną zmianę koloru w zależności od wartości , miłym akcentem :-) – kleopatra

+0

@ David Kroukamp Czy to znaczy, że mogę przesłonić metody setBackground i setForeground JProgressBar i zastosować domyślne ustawienia UI? – mbasol

+0

@mbasol Tak, nie widzę powodu, dla którego nie można tego zrobić. –

3

Nimbus obsługuje skórek dla poszczególnych składników, takich jak już udzielono odpowiedzi w innych QA. Stosowane do JProgressBar „bar”, które znaczy konfigurację instancji z niestandardowym foregroundPainter jak:

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 (brzydki patrząc) malarz byłoby coś takiego:

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

} 

Aby uczynić go wizualnie miłe, zajrzyj do ProgressBarPainter: jest to pakiet prywatny, więc nie możesz zrobić nic poza zrozumieniem, w jaki sposób osiąga on gradienty/ścieżki obrazowania i zrobić to samo w niestandardowej implementacji.

+1

+1 nie zapomnij "ProgressBar [Enabled + Finished] .foregroundPainter" lub powróci do oryginalnego na 100% compilation –

+1

@DavidKroukamp dobry połów - dzięki za heads-up :-) – kleopatra