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.
Ah, you might wan to look at JLayer (or JXLayer for < Java 1.7) for transparency then.
See the tutorial
Well, here's your first problem:
Graphics2D g2 = (Graphics2D) comp.getGraphics().create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, t));
comp.paint(g2);
g2.dispose();
You should only be painting components inside a call to paint(Graphics g)
. Painting during a call to your setTransparency
method is A Bad Idea, because it will be erased the next time Swing decides to call paint
. You need to make your component handle it's own transparency inside the paintComponent
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 then th 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 the opaque
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:
void setTransparency(Window w, double t) {
try {
setOpacity17(w, t);
return;
}
catch (NoSuchMethodError e) {
System.err.println("JRE *is* less than 1.7!"); // We know the JRE must be < 1.7 because the right methods are known to exist in 1.7.
}
catch (Throwable t) {
t.printStackTrace();
}
try {
setOpacity16(w, t);
}
catch (Throwable t) {
System.err.println("Boom!");
}
}
void setOpacity17(Window w, double t) {
...
}
void setOpacity16(Window w, double t) {
...
}
That's a lot cleaner. Note the return
that will short-circuit the function if the 1.7 version succeeds.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.