如何在 Java 中使轻量级 Swing 或 AWT 组件半透明
前段时间尝试为Swing/AWT组件实现半透明的方法,现在才第一次尝试。然而,在实施过程中,UI 中出现了一些问题。该方法的代码如下:
public static void setTransparency(Component comp, float t)
{
try
{
if (comp instanceof Window)
{
try
{
//For JDK 1.7
((Window) comp).setOpacity(t);
}
catch (Throwable th)
{
System.err.println("JRE may be less than 1.7!");
if (!th.getClass().isInstance(new NoSuchMethodError()))
th.printStackTrace();
try
{
//For JDK 1.6
com.sun.awt.AWTUtilities.setWindowOpacity((Window) comp, t);
}
catch (Throwable th1)
{
throw new UnsupportedOperationException("It seems that transparency is not supported", th1);
}
}
}
else
{
if (comp instanceof JComponent)
((JComponent)comp).setOpaque(false);
Graphics2D g2 = (Graphics2D) comp.getGraphics().create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, t));
comp.paint(g2);
g2.dispose();
}
}
catch (Throwable th)
{
throw new UnsupportedOperationException("Transparency might not be supported", th);
}
}
运行时,组件的外观没有变化。 是否有人建议将 Swing 或 AWT 组件设为半透明且 100% 可靠? 这仅适用于轻量级组件,因为重量级透明度是单独覆盖的且 100% 可靠,如上所示。
A while ago, I tried to implement a semitransparency method for Swing/AWT components, and just now tried it out for the first time. However, several glitches in the UI surface upon implementation. The code of the method is below:
public static void setTransparency(Component comp, float t)
{
try
{
if (comp instanceof Window)
{
try
{
//For JDK 1.7
((Window) comp).setOpacity(t);
}
catch (Throwable th)
{
System.err.println("JRE may be less than 1.7!");
if (!th.getClass().isInstance(new NoSuchMethodError()))
th.printStackTrace();
try
{
//For JDK 1.6
com.sun.awt.AWTUtilities.setWindowOpacity((Window) comp, t);
}
catch (Throwable th1)
{
throw new UnsupportedOperationException("It seems that transparency is not supported", th1);
}
}
}
else
{
if (comp instanceof JComponent)
((JComponent)comp).setOpaque(false);
Graphics2D g2 = (Graphics2D) comp.getGraphics().create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, t));
comp.paint(g2);
g2.dispose();
}
}
catch (Throwable th)
{
throw new UnsupportedOperationException("Transparency might not be supported", th);
}
}
When run, the component does not change in appearance. Does anyone have a suggestion for making a Swing or AWT component semitransparent that is 100% reliable? This only applies to lightweight components, as heavyweight transparency is separately covered and 100% reliable, as shown above.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
啊,那么您可能想查看 JLayer(或
请参阅教程
Ah, you might wan to look at JLayer (or JXLayer for < Java 1.7) for transparency then.
See the tutorial
好吧,这是您的第一个问题:
您应该只在调用
paint(Graphics g)
内绘制组件。在调用setTransparency
方法期间进行绘制是一个坏主意,因为下次 Swing 决定调用paint
时它将被删除。您需要让组件在paintComponent
方法中处理它自己的透明度。还有这个:
if (!th.getClass().isInstance(new NoSuchMethodError()))
你到底在做什么?简单的
catch (NoSuchMethodError e)
有什么问题?或者,如果您真的想使用instanceof,那么第一个instanceof NoSuchMethodError
?顺便说一句,@WalterLaan 和 @JimN 知道他们在说什么。
setOpaque
(或更准确地说,isOpaque
)是 Swing 引擎的渲染提示,可以帮助它优化其操作。检查javadocs,你就会明白我的意思。这与打开或关闭背景无关。嗯,这并不完全正确 - 默认情况下,JComponent
会巧妙地使用opaque
属性来在适当的情况下自动绘制背景,但是如果如果你正在处理你自己的画,那么你的聪明才智可能会被推翻。编辑:关于NoSuchMethodError。看看这个:
那干净多了。请注意,如果 1.7 版本成功,
return
将使函数短路。Well, here's your first problem:
You should only be painting components inside a call to
paint(Graphics g)
. Painting during a call to yoursetTransparency
method is A Bad Idea, because it will be erased the next time Swing decides to callpaint
. You need to make your component handle it's own transparency inside thepaintComponent
method.Also this:
if (!th.getClass().isInstance(new NoSuchMethodError()))
What on earth are you doing? What's wrong with a simple
catch (NoSuchMethodError e)
? Or, if you really want to use instanceof thenth instanceof NoSuchMethodError
?By the way, @WalterLaan and @JimN know what they're talking about.
setOpaque
(or, more accurately,isOpaque
) is a rendering hint to the Swing engine that can help it optimize it's operation. Check the javadocs and you'll see what I mean. It's nothing to do with turning the background on or off. Well, that's not entirely true -JComponent
, by default, does some cleverness with theopaque
property to automatically paint the background if appropriate, but if you're handling your own painting then that cleverness will probably be overridden.EDIT: Regarding the NoSuchMethodError. Take a look at this:
That's a lot cleaner. Note the
return
that will short-circuit the function if the 1.7 version succeeds.