问题
Continuing from Setting the colors of a JProgressBar text I would like to be able to set the text colors of JProgressBar
s 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 JProgressBar
s.
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 JProgressBar
s 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