如何在不改变外观的情况下为多个JProgressBars独立设置JProgressBar文本颜色

时间:2014-03-14 20:09:29

标签: java swing look-and-feel jprogressbar

继续Setting the colors of a JProgressBar text我希望能够根据进程状态设置程序中JProgressBar的文本颜色,而不会偏离系统外观。

Setting the colors of a JProgressBar text的答案中,我看起来只能设置文本颜色而不会将UI更改为一组值,所以无论前景和进度如何,我都可以选择看起来不错的中性值,但我想完全自定义JProgressBar s。

下面是一些示例代码,其中包含三种外观并尝试从“好”状态切换到“坏”状态。显然,BasicProgressBarUI可以完全切换,但金属默认和系统外观不能,可以在创建时为它们分配不同的默认值,但一旦创建,它们似乎是固定的。

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

}

如SSCCE所示,可以独立设置文本颜色,但不能动态设置。所有JProgressBar都以某种形式的“好”或“中立”状态开始,最终可能会变为“不良”状态。

1 个答案:

答案 0 :(得分:3)

如您所见,UI委托控制它如何使用指定的颜色。虽然动态更新颜色在表面上很吸引人,但它会引起色调和对比度方面的可用性问题。相反,请考虑添加动态着色的BorderIcon。可以看到前者的一个例子here;可以看到后者的一个例子here