Wie kann man eine Statusanzeige erzeugen, deren Farbigkeit sich in Abhängigkeit vom angezeigten Statuswert ändert?

Eine Statusanzeige kann mit Java recht einfach mit Hilfe der Klasse javax.swing.JProgressBar erzeugt werden, deren Erscheinungsbild jedoch angepasst werden muss. Die Klasse JProgressBar stellt bereits einige Methoden zur Anpassung der Komponente bereit, eine Einfärbung des Statusbalkens ist jedoch leider nicht vorgesehen. Ein Blick in den Quelltext verrät, dass eine JProgressBar ihre Erscheinung üblicherweise von der Klasse javax.swing.plaf.basic.BasicProgressBarUI erhält. Zur Anpassung muss diese somit überschrieben werden.
Die Klasse FarbigeProgressBar demonstriert das Vorgehen.

Sie erweitert die Klasse JProgressBar. Im Konstruktor, dem der Minimum- und Maximumwert der Anzeige übergeben wird, wird eine Instanz der BasicProgressBarUI erzeugt. Sie könnte für das hier gezeigte Vorhaben völlig leer bleiben. Zur Demonstration überschreibt sie jedoch die beiden Methoden getSelectionForeground() und getSelectionBackground(), mit denen die Farben des Textes im Statusbalken angepasst werden können. Die erste Methode ist für die Textfarbe über dem "gefüllten" Balken, die zweite für die Textfarbe vor dem leeren Hintergrund des Balkens verantwortlich.
Das UI wird mittels setUI der JProgressBar zugeordnet. Die anderen im Konstruktor der Klasse aufgerufenen Methoden stellen einige gängige Möglichkeiten dar, eine JProgressBar den eigenen Bedürfnissen anzupassen.

class FarbigeProgressBar extends JProgressBar {

    public FarbigeProgressBar(int start, int end) {
        [...]
        BasicProgressBarUI ui = new BasicProgressBarUI() {
            protected Color getSelectionForeground(){
                return Color.BLACK;
            }
            protected Color getSelectionBackground(){
                return Color.BLACK;
            }
        };
        setUI(ui);
    }
}

Die Klasse FarbigeStatusAnzeige stellt neben einem JButton zum Start des kleinen Programms den JFrame bereit, auf dem die ProgressBar angezeigt wird. Außer der main()-Methode zum Aufruf der Applikation ist als einzige Methode nur der Konstruktor vorhanden. Neben den üblichen Konfigurationen des JFrame wird in ihm ein Runnable-Objekt gebildet, das es ermöglicht, die Statusanzeige in einem eigenen Thread laufen zu lassen, um andere Kompomenten, wie z.B. den Button bedienbar zu halten.
Hier werden zunächst zwei Variablen für die Farbsteuerung deklariert und mit entsprechenden Werten initialisiert. Ziel ist eine Anzeigefarbigkeit, die von Grün über Gelb nach Rot läuft. Grün erhält somit zunächst den Maximal-, Rot den Minimalwert. Das Gelb ergibt sich aus der additiven Mischung von Rot und Grün. Blau ist gar nicht beteiligt und wird somit durchgängig auf 0 gesetzt. Um ein Ein- und Ausblenden der jeweiligen Farben zu erreichen wird ein konstanter Faktor definiert, der im farbigen Übergangsbereich addiert bzw. subtrahiert wird.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.basic.BasicProgressBarUI;

public class FarbigeStatusAnzeige extends JFrame {

    FarbigeProgressBar bar;
    JButton button;
    int max = 4000, min = 0;

    public FarbigeStatusAnzeige() {

        bar = new FarbigeProgressBar(min, max);
        bar.setValue(max);
        bar.setStringPainted(true);

        final Runnable runnable = new Runnable() {
            int rot = 0, gruen = 255;
            double faktor = max / 255 / 2;

            public void run() {
                for (int i = max; i > min; i--) {
                    if (i < max / 5 * 2) {
                        rot += faktor / 5;
                    }
                    if (i < max / 10) {
                        gruen -= faktor / 25;
                        rot += faktor / 15;
                    }
                    
                    rot = rot > 255 ? 255 : rot;
                    rot = rot < 0 ? 0 : rot;
                    gruen = gruen > 255 ? 255 : gruen;
                    gruen = gruen < 0 ? 0 : gruen;
                    bar.setForeground(new Color(rot, gruen, 0));
                    bar.setValue(i);
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException ex) {
                    }
                }
                rot = 0;
                gruen = 255;
            }
        };

        button = new JButton("start");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Thread thread = new Thread(runnable);
                thread.start();
            }
        });
        setLayout(new BorderLayout());
        add(button, BorderLayout.SOUTH);
        add(bar, BorderLayout.CENTER);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new FarbigeStatusAnzeige();
    }
}

class FarbigeProgressBar extends JProgressBar {

    public FarbigeProgressBar(int start, int end) {
        setMinimum(start);
        setMaximum(end);
        setForeground(SystemColor.window);
        setBackground(SystemColor.window);
        setBorder(new EmptyBorder(3, 5, 3, 5));
        Dimension size = new Dimension(300, 20);
        setPreferredSize(size);
        setMaximumSize(size);
        setMinimumSize(size);
        BasicProgressBarUI ui = new BasicProgressBarUI() {
            protected Color getSelectionForeground(){
                return Color.BLACK;
            }
            protected Color getSelectionBackground(){
                return Color.BLACK;
            }
        };
        setUI(ui);
    }
}

In der Methode run() des Threads durchläuft eine Schleife die Anzeigewerte vom Maximum zum Minimum und setzt für jeden Wert die Vordergrundfarbe. Diese wird durch zwei if-Verzweigungen definiert, in denen die Abnahme und Zunahme der Farbanteile für die beiden Übergangsbereiche berechnet werden. Sie sind, wie auch die Farbwerte und der Berechnungsfaktor, an die eigenen Wünsche anpassbar. Wichtig ist, dass die Werte nicht den erlaubten Bereich von minimal 0 und maxima 255 unter- bzw. überschreiten. Der letzte Ausdruck im Konstruktor simuliert einen zeitintensiven Bearbeitungsvorgang, indem der Thread für kurze Zeit zum Pausieren veranlasst wird.