如何在Java中制作一个半透明的轻量级Swing或AWT组件

时间:2011-12-15 05:24:24

标签: java swing awt transparency

不久前,我尝试为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);
    }
  }

运行时,组件的外观不会改变。 是否有人建议制作一个100%可靠的Swing或AWT组件半透明?这仅适用于轻量级组件,因为重量级透明度是单独覆盖且100%可靠,如上所示。

2 个答案:

答案 0 :(得分:1)

啊,你可能想看看JLayer(或JXLayer for< Java 1.7)的透明度。

请参阅tutorial

答案 1 :(得分:0)

嗯,这是你的第一个问题:

Graphics2D g2 = (Graphics2D) comp.getGraphics().create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, t));
comp.paint(g2);
g2.dispose();

您应该只在paint(Graphics g)的调用中绘制组件。在调用setTransparency方法时进行绘画是一个不好的主意,因为在下次Swing决定调用paint时它会被删除。您需要让组件在paintComponent方法中处理它自己的透明度。

此外:if (!th.getClass().isInstance(new NoSuchMethodError()))

你到底在做什么?简单的catch (NoSuchMethodError e)有什么问题?或者,如果确实想要使用instanceof,那么th instanceof NoSuchMethodError

顺便说一句,@ WalterLaan和@JimN知道他们在谈论什么。 setOpaque(或者,更确切地说,isOpaque)是Swing引擎的渲染提示,可以帮助它优化其操作。检查javadocs,你会明白我的意思。这与打开或关闭背景无关。好吧,那不是完全是真的 - JComponent,默认情况下,使用opaque属性做一些聪明,如果合适的话自动绘制背景,但是如果你正在处理自己的然后画那个聪明可能会被覆盖。

编辑:关于NoSuchMethodError。看看这个:

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) {
    ...
}

那更清洁了。注意return,如果1​​.7版本成功,将使功能短路。