我有一个应用程序在几个地方使用禁用的 JTextFields,这些地方旨在透明 - 允许背景显示而不是文本字段的正常背景。
运行新的 Nimbus LAF 时,这些字段是不透明的(尽管设置了 setOpaque(false)),并且我的 UI 已损坏。就好像 LAF 忽略了 opaque 属性。明确地设置背景颜色在几个地方都很困难,并且由于背景图像实际上不起作用,因此不是最佳的 - 它仍然在顶部绘制它的 LAF 默认背景,留下类似边框的外观(下面的启动屏幕有背景明确设置为匹配图像)。
关于如何让 Nimbus 不为 JTextField 绘制背景的任何想法?
注意:我需要一个 JTextField,而不是 JLabel,因为我需要线程安全的 setText() 和包装能力。
注意:我的后备立场是继续使用系统 LAF,但 Nimbus 看起来确实要好得多。
请参阅下面的示例图像。
结论
这种行为令人惊讶是由于对 setOpaque() 的作用的误解——来自 Nimbus 错误报告:
这是 Swing 的原始设计以及多年来一直令人困惑的问题。问题是 setOpaque(false) 在退出 LAF 时产生了副作用,即隐藏背景,这并不是它真正的用途。应该说组件有透明的部分,swing 应该在它后面绘制父组件。
不幸的是,Nimbus 组件似乎也不支持 setBackground(null),否则这将是停止背景绘制的推荐方法。设置一个完全透明的背景对我来说似乎不直观。
在我看来,setOpaque()/isOpaque() 是一个错误的公共 API 选择,应该只是:
public boolean isFullyOpaque();
我这样说是因为 isOpaque()==true 是与 Swing 的合同,组件子类将负责绘制它的整个背景——这意味着父级可以根据需要跳过绘制该区域(这是一个重要的性能增强)。外部的东西不能直接(合法地)改变这个契约,它的实现可以被编码到组件中。
所以组件的不透明度不应该使用 setOpaque() 设置。相反,像 setBackground(null) 这样的东西应该会导致许多组件“没有背景”,因此变得不完全不透明。例如,在理想世界中,大多数组件应该有一个 isOpaque(),如下所示:
public boolean isOpaque() { return (background!=null); }