Java Nimbus LAF与透明文本字段

问题描述 投票:11回答:4

我有一个应用程序在几个地方使用禁用的JTextFields是透明的 - 允许显示背景而不是文本字段的正常背景。

运行新的Nimbus LAF时,这些字段是不透明的(尽管设置了setOpaque(false)),并且我的UI被破坏了。好像LAF忽略了不透明的属性。设置背景颜色 明确地在几个地方都很难,并且由于背景图像而不是最佳的 实际上它不起作用 - 它仍然在顶部绘制LAF默认背景,留下类似边框的外观(下面的启动画面明确设置背景以匹配图像)。

关于如何让Nimbus不为JTextField绘制背景的任何想法?

注意:我需要一个JTextField而不是JLabel,因为我需要线程安全的setText()和包装功能。

注意:我的后备位置是继续使用系统LAF,但Nimbus确实看起来好多了。

见下面的示例图片。


结论

这种行为的意外是由于对Nimbus错误报告中的setOpaque()意图做错误的解释:

这是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); }

Example

alt text

java swing nimbus
4个回答
17
投票

我上周使用JTextPane遇到了同样的问题。当使用除nimbus之外的任何外观时,setOpaque()方法按预期工作。显然,nimbus的外观和感觉改变了我们对许多组件的setOpaque()所期望的行为。根据您的看法,它可以被视为一个错误。检查这个sun bugid的评论:

nimbus opaque bug

对我有用的解决方法是:

myPane.setOpaque(false); // added by OP
myPane.setBorder(BorderFactory.createEmptyBorder());
myPane.setBackground(new Color(0,0,0,0));

OP的注意事项:我还必须确保JTextField的setOpaque(false),以便绘制父背景 - 只是想为其他人提及这一点,以防他们尝试使用setOpaque(true),就像我一样。


0
投票

嘿有软件猴子。

mmhh如何安装UI的子类替换实际上尊重setOpaque行为。

我认为它类似于setUI或类似的东西。

您可以获取灵气的源代码,看看那里有什么(如果有的话),将其子类化并安装“固定”的。

你的声音很有趣,你有任何我能看到的截图吗?


0
投票

来自javadoc

public void setBackground(Color bg)

设置此组件的背景颜色。仅当组件不透明时才使用背景颜色,并且仅使用JComponent或ComponentUI实现的子类。 JComponent的直接子类必须覆盖paintComponent才能使用此属性。

尊重这个属性取决于外观和感觉,有些人可能会选择忽略它。


0
投票

我认为问题是如何解释“不透明”和“背景”。对于JTextfield,有一个问题:“哪些可见部分是背景?”。我将“背景”定义为边界矩形的部分,它们不是由组件绘制的。对于“圆形”按钮,例如,这将是圆形外的角。因此我会说JTextfield没有可见的背景!它有一个矩形的形状,你所采取的背景不是场的背景,而是场的画布。


来自OP的反驳

这是一个有趣的想法,值得回答未来观众的答案(而不是评论)。

我不同意。我认为边界之外的组件部分不是组件的一部分 - 它在组件之外。具有圆角的区域必然是非不透明的,因为它不能负责绘制它的整个矩形区域 - 这是所有组件的尺寸为矩形的副作用。

我认为这种考虑使得isOpaque()的现有(和被误解的)含义的论证。它也使我的论点setOpaque()不应该存在,并且setBackground(null)应该导致组件不绘制背景。

我会提出,文本字段的背景确实是其边界内区域的颜色,我认为你不会发现很多人会对此作出直观的结论 - 因此有背景适用于该地区的服从API用户的最小惊喜规则。

© www.soinside.com 2019 - 2024. All rights reserved.