【问题标题】:How to set JProgressBar text color independently for multiple JProgressBars without changing Look and Feel如何在不改变外观的情况下为多个 JProgressBar 独立设置 JProgressBar 文本颜色
【发布时间】:2014-03-14 20:09:29
【问题描述】:

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

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

下面是一些示例代码,具有三种外观,试图从“好”状态切换到“坏”状态。显然,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 所示,可以独立设置文本颜色,但不能动态设置。所有JProgressBars 都以某种形式的“良好”或“中性”状态开始,最终可能变为“不良”状态。

【问题讨论】:

  • 我有点困惑:你想根据进度状态动态改变JProgressBar的颜色吗?
  • 在我的程序中,它实际上是基于另一个线程控制的文件传输的状态,颜色编码是基于线程/传输的状态。我在想绿色代表工作,黄色代表失速,红色代表任何过早的断开或故障。我可以毫无问题地获取状态并更改栏的颜色。
  • 可以setStringPainted(false); 自己绘制文本。我相信这是唯一的方法。我建议不要对系统 LAF 执行此操作。例如,在完成条为蓝色的 Mac OS X 上,它看起来会很糟糕。

标签: java swing look-and-feel jprogressbar


【解决方案1】:

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

【讨论】:

  • 没有告诉我该怎么做,但它确实给了我一个很好的理由不这样做。
  • 我会使用PropertyChangeEvent,对于example,来通知辅助指标。
猜你喜欢
  • 2015-04-04
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多