2013-01-17 33 views
5

Sto utilizzando il componente JProgressBar insieme ai valori predefiniti dell'interfaccia utente Nimbus. Il problema è che quando voglio cambiare manualmente il colore della barra di ogni progressbar, io uso BasicProgressBarUI impostando la funzione JProgressBar.setUI(). Questo crea più problemi perché vorrei solo cambiare il colore della barra e sembra che perdo l'aspetto predefinito della barra dei comandi di jprogress (Border, backgroundcolor scompare).JProgressBar Modifica dinamicamente del colore della barra

Così posso impostare UIDefaults di Nimbus ProgressBar quando il codice viene inizializzato. Funziona.

Ma voglio cambiare dinamicamente il colore della barra di ogni barra di avanzamento.

C'è un altro modo per cambiare il colore della barra di 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

per una migliore aiuto prima inserire una [SSCCE] (http://sscce.org/), a breve, eseguibile, compilabile, altrimenti fare per cercare, Google può restituisce che – mKorbel

+2

See [questo] (http://stackoverflow.com/questions/7174420/change-colors-for-jprogressbar-with-nimbus) domanda/risposta simile, che mostra come usare 'UIDefaults' e' putClientProperty' per cambiare un singolo colore 'JProgressBar' –

+0

Il problema corrente è Quando cambio il colore della barra usando setForeground (Color.GREEN); cambia il Colore SelectionBackground. E sembra che setBackgroundColor (Color.RED); il comando non fa nulla – mbasol

risposta

4

+1 a Kelopatra per essere il primo.

Ecco un esempio che ho fatto:

Il colore JProgressBar è initaily impostata tramite:

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

sul 50% di avanzamento il colore sarà cambiato per 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);       
} 

test .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 per cambiare dinamicamente il colore in base al valore , bel tocco :-) – kleopatra

+0

@David Kroukamp Significa che posso sovrascrivere setBackground e setForeground metodi di JProgressBar e applicare UI Defaults giusto? – mbasol

+0

@mbasol Sì, non vedo alcun motivo per cui ciò non può essere fatto –

3

Nimbus supporta la scomposizione per componente, come già risposto nell'altro QA. Applicato ad un "bar" JProgressBar che significa configurare l'istanza con un foregroundPainter personalizzato come:

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

Il mimimal (brutto cercando) pittore sarebbe qualcosa di simile:

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

} 

Per rendere più visivamente piacevole, Dai un'occhiata a ProgressBarPainter: è un pacchetto privato, quindi non puoi fare molto altro che capire come raggiunge il suo gradiente/percorso pittura e fare lo stesso in un'implementazione personalizzata.

+1

+1 non dimenticare "ProgressBar [Enabled + Finished] .foregroundPainter" o ritornerà all'originale al 100% di compeletion –

+1

@DavidKroukamp good catch - grazie per l'heads up :-) – kleopatra

Problemi correlati