带有透明文本字段的Java Nimbus LAF

带有透明文本字段的Java Nimbus LAF,java,swing,nimbus,Java,Swing,Nimbus,我有一个应用程序,它在几个地方使用禁用的JTextFields,这些地方都是透明的——允许背景显示,而不是文本字段的正常背景 运行新的Nimbus LAF时,这些字段是不透明的(尽管设置了setOpaque(false)),并且我的UI被破坏。这就好像LAF忽略了不透明属性。显式设置背景色在很多地方都很困难,而且由于背景图像实际上不起作用,因此不如最佳设置-它仍然在顶部绘制LAF默认背景,留下类似边框的外观(下面的启动屏幕将背景显式设置为与图像匹配) 关于如何让Nimbus不为JTextFiel

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

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

关于如何让Nimbus不为JTextField绘制背景,有什么想法吗

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

注意:我的退路是继续使用系统LAF,但Nimbus看起来确实更好

请参见下面的示例图像


结论 对这种行为的惊讶是由于对set不透明()的作用的误解——来自Nimbus bug报告:

这是Swing最初设计的一个问题,也是多年来一直令人困惑的问题。问题是setOpaque(false)在退出LAFs时产生了一个副作用,即隐藏背景,而这并不是它真正的用途。可以这么说,组件my具有透明部分,swing应该在其后面绘制父组件

不幸的是,Nimbus组件似乎也不支持setBackground(null),否则这将是停止背景绘制的推荐方法。设置一个完全透明的背景对我来说似乎不太直观

在我看来,setOpaque()/isOpaque()是一个错误的公共API选择,它应该是:

public boolean isFullyOpaque();
我这样说是因为isOpaque()==true是与Swing的约定,组件子类将负责绘制整个背景-这意味着父类可以根据需要跳过绘制该区域(这是一个重要的性能增强)。外部事物不能直接(合法地)更改此合同,其履行可能被编码到组件中

因此,不应使用setOpaque()设置组件的不透明度。相反,像setBackground(null)这样的东西应该会导致许多组件“没有背景”,因此变得不完全不透明。例如,在理想情况下,大多数组件都应该有一个如下所示的isOpaque():

public boolean isOpaque() { return (background!=null); }


嘿,这里有软件猴子

安装UI的子类替换,实际上尊重set不透明行为,怎么样

我认为它是像setUI之类的东西

你可以抓取nimbus的源代码,看看有什么坏掉了(如果有的话),对它进行子类化,然后安装“修复的”一个


你的文章听起来很有趣,你有我们可以看到的截图吗?

我上周在使用JTextPane时遇到了同样的问题。当使用除nimbus之外的任何外观时,set不透明()方法都能正常工作。显然,nimbus的外观改变了我们对许多组件使用set不透明()所期望的行为。根据您对它的看法,它可以被视为一个bug。检查此sun bugid上的注释:

对我有效的解决办法是:

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


OP中的注释:我还必须确保JTextField的setOpaque(false),以便绘制父背景-只是想向其他跟随者提及这一点,以防他们像我一样尝试过setOpaque(true)。

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


OP的反驳

这是一个非常有趣的想法,值得在未来观众的回答中回应(而不是在评论中)

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

我认为这种考虑为isOpaque()的现有(和被误解)含义提供了理由。它还提出我的论点,setOpaque()不应该存在,setBackground(null)应该导致组件不绘制背景

我想说的是,文本字段的背景确实是其边界内区域的颜色,我认为你不会发现有太多人质疑这一直观结论——因此,将背景应用于该区域符合API用户最不惊讶的规则。

来自javadoc

公共空地(彩色背景)

设置此组件的背景色。背景色是 仅当组件不透明时使用, 并且仅通过JComponent的子类 或组件UI实现。直接的 JComponent的子类必须重写 您必须尊重此财产

这取决于外观和感觉,以尊重这一财产,有些人可能会选择 忽略它


你已经浏览过这个包裹了吗?src.zip\com\sun\java\swing\plaf\nimbust这看起来很有希望;今晚将在我的应用程序中尝试。T