我们有一个可以在“白天”(高对比度)和“夜间”(低对比度)模式之间切换的程序.这是通过动态更改外观来完成的.它适用于几乎所有组件,但是有一些忽略了背景颜色的变化.特别是,我注意到按钮,组合框和表标题都忽略了PLAF中的更改.
这是带有按钮的示例程序.难道我做错了什么?这是某种依赖于操作系统的行为吗? (我在OSX上)
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.plaf.ColorUIResource;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Demo extends JFrame {
public static void main(String[] args) {
new Demo();
}
public Demo() {
setTitle("PLAF button test");
final Demo thisWindow = this;
final JButton button = new JButton("Click me!");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Color curColor = UIManager.getColor("Button.background");
ColorUIResource targetColor;
if (curColor.equals(new Color(32, 32, 32))) {
targetColor = new ColorUIResource(192, 192, 192);
}
else {
targetColor = new ColorUIResource(32, 32, 32);
}
System.out.println("Setting new color to " + targetColor +
" because old color was " + curColor);
UIManager.put("Button.background", targetColor);
SwingUtilities.updateComponentTreeUI(thisWindow);
}
});
add(button);
setMinimumSize(new java.awt.Dimension(200, 200));
setVisible(true);
}
}
这是我运行该程序并单击按钮时得到的输出:
Setting new color to javax.swing.plaf.ColorUIResource[r=32,g=32,b=32] because old color was com.apple.laf.AquaImageFactory$SystemColorProxy[r=238,g=238,b=238]
Setting new color to javax.swing.plaf.ColorUIResource[r=192,g=192,b=192] because old color was javax.swing.plaf.ColorUIResource[r=32,g=32,b=32]
Setting new color to javax.swing.plaf.ColorUIResource[r=32,g=32,b=32] because old color was javax.swing.plaf.ColorUIResource[r=192,g=192,b=192]
Setting new color to javax.swing.plaf.ColorUIResource[r=192,g=192,b=192] because old color was javax.swing.plaf.ColorUIResource[r=32,g=32,b=32]
因此,UIManager认为颜色正在改变,但是屏幕上的外观颜色没有改变.
任何建议表示赞赏.感谢您的时间.
解决方法:
Is this an OS-dependent behavior somehow?
该效果仅取决于UI委托来控制组件的外观,并且每个受支持的平台都定义了默认值Look & Feel.在Mac OS X上,默认值为com.apple.laf.AquaLookAndFeel;这是对应的source.如UIManager默认值(引用为here)所示,“ Button.background”的UIManager键的浅灰色值为
com.apple.laf.AquaImageFactory$SystemColorProxy[r=238,g=238,b=238]
但是分配的空间完全被本机组件覆盖.类似的效果会使“ RadioBUtton.icon”显示的浅粉红色占位符模糊.一些缓解策略:
>根据建议的here,您可以设置封闭的JPanel的背景.
>如建议here所示,您可以使用setOpaque()着色某些背景;较深的阴影可能会有所帮助.
JButton b = new JButton("Test");
b.setOpaque(true);
b.setBackground(Color.red.darker());
>如果您使用的是Border
,请记住要“将组件放入JPanel并在JPanel上设置边框”.
>使用诸如here所示的控件,让用户选择首选的外观.感觉;将选择保留在java.util.prefs.Preferences的实例中.
>将用户定向到Mac OS X Accessibility“系统偏好设置”面板中的对比度选项.
>在合适的谓词中包装特定于平台的代码.
if (System.getProperty("os.name").startsWith("Mac OS X")) {
// Specific to Mac OS X
}