How to set JProgressBar text color independently for multiple JProgressBars without changing Look and Feel

人走茶凉 提交于 2019-12-24 11:32:51

问题


Continuing from Setting the colors of a JProgressBar text I would like to be able to set the text colors of JProgressBars in my program dependent upon process state and without moving away from System look and feel.

From one of the answers on Setting the colors of a JProgressBar text , it looks like I can only set text colors without changing the UI to a single set of values, so I could choose neutral values that look decent regardless of the foreground and progress, but I would like to fully customize the JProgressBars.

Below is some example code with three look and feels trying to switch from "good" to "bad" status. Obviously, the BasicProgressBarUI can be switched over fully, but the Metal default and System look and feel cannot, they can be assigned different default values at creation, but once created, they appear to be fixed.

SSCCE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.basic.BasicProgressBarUI;


@SuppressWarnings("serial")
public class ProgressBarTester extends JFrame {

    public ProgressBarTester() {
        super( "Progress Bar Tester" );
        setLayout( new BorderLayout() );

        JPanel goodPanel = new JPanel( new FlowLayout() );
        goodPanel.setLayout( new FlowLayout() );
        JPanel badPanel = new JPanel( new FlowLayout() );
        badPanel.setLayout( new FlowLayout() );

        JProgressBar plainBarG = new JProgressBar();
        plainBarG.setValue( 50 );
        plainBarG.setStringPainted( true );
        plainBarG.setForeground( Color.green.darker() );

        plainBarG.setUI( new BasicProgressBarUI() {

            protected Color getSelectionBackground() {
                return Color.green.darker();
            }
            protected Color getSelectionForeground() {
                return Color.white;
            }
        } );
        goodPanel.add( plainBarG );


        JProgressBar plainBarB = new JProgressBar();
        plainBarB.setValue( 50 );
        plainBarB.setStringPainted( true );
        plainBarB.setForeground( Color.red.darker() );

        plainBarB.setUI( new BasicProgressBarUI() {

            protected Color getSelectionBackground() {
                return Color.red.darker();
            }
            protected Color getSelectionForeground() {
                return Color.black;
            }
        } );
        badPanel.add( plainBarB );

        UIManager.put( "ProgressBar.selectionForeground", Color.white );
        UIManager.put( "ProgressBar.selectionBackground", Color.green.darker() );

        JProgressBar javaDefaultG = new JProgressBar();
        javaDefaultG.setValue( 50 );
        javaDefaultG.setStringPainted( true );
        javaDefaultG.setForeground( Color.green.darker() );
        goodPanel.add( javaDefaultG );

        UIManager.put( "ProgressBar.selectionForeground", Color.black );
        UIManager.put( "ProgressBar.selectionBackground", Color.red.darker() );

        JProgressBar javaDefaultB = new JProgressBar();
        javaDefaultB.setValue( 50 );
        javaDefaultB.setStringPainted( true );
        javaDefaultB.setForeground( Color.red.darker() );
        badPanel.add( javaDefaultB );

        try {
            UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        UIManager.put( "ProgressBar.selectionForeground", Color.white );
        UIManager.put( "ProgressBar.selectionBackground", Color.green.darker() );

        JProgressBar systemG = new JProgressBar();
        systemG.setValue( 50 );
        systemG.setStringPainted( true );
        systemG.setForeground( Color.green.darker() );
        goodPanel.add( systemG );

        UIManager.put( "ProgressBar.selectionForeground", Color.black );
        UIManager.put( "ProgressBar.selectionBackground", Color.red.darker() );

        JProgressBar systemB = new JProgressBar();
        systemB.setValue( 50 );
        systemB.setStringPainted( true );
        systemB.setForeground( Color.red.darker() );
        badPanel.add( systemB );

        this.add( goodPanel, BorderLayout.NORTH );
        this.add( badPanel, BorderLayout.SOUTH );

        pack();
        setVisible( true );

        try {
            Thread.sleep( 2000 );
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        plainBarG.setForeground( Color.red.darker() );
        plainBarG.setUI( new BasicProgressBarUI() {
            protected Color getSelectionBackground() {
                return Color.red.darker();
            }
            protected Color getSelectionForeground() {
                return Color.black;
            }
        } );
        plainBarB.setForeground( Color.green.darker() );
        plainBarB.setUI( new BasicProgressBarUI() {

            protected Color getSelectionBackground() {
                return Color.green.darker();
            }
            protected Color getSelectionForeground() {
                return Color.white;
            }
        } );

        javaDefaultG.setForeground( Color.red.darker() );
        javaDefaultB.setForeground( Color.green.darker() );

        systemG.setForeground( Color.red.darker() );
        systemB.setForeground( Color.green.darker() );
    }

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

}

As shown in the SSCCE, it is possible to independently set the text colors, but not to do so dynamically. All JProgressBars start with some form of "good" or "neutral" status and may eventually change to a "bad" status.


回答1:


As you observe, the UI delegate controls how it uses the specified colors. While updating the colors dynamically is superficially appealing, it invites usability problems with respect to hue and contrast. Instead, consider adding a dynamically colored Border or Icon. An example of the former is seen here; an example of the latter is seen here.



来源:https://stackoverflow.com/questions/22414811/how-to-set-jprogressbar-text-color-independently-for-multiple-jprogressbars-with

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!