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

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

下面是一些具有三种外观的示例代码,试图从“好”状态切换到“坏”状态。显然,BasicProgressBarUI可以完全切换,但是Metal默认值和System外观不能,在创建时可以为它们指定不同的默认值,但是一旦创建,它们似乎是固定的。

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都以某种形式的“好”或“中立”状态开始,并最终可能变为“坏”状态。

最佳答案

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

关于java - 如何在不更改外观的情况下为多个JProgressBar分别设置JProgressBar文本颜色,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22414811/

10-10 19:28