【问题标题】:How to make a lightweight Swing or AWT component translucent in Java如何在 Java 中使轻量级 Swing 或 AWT 组件半透明
【发布时间】:2012-01-20 21:05:09
【问题描述】:

前段时间,我尝试实现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% 可靠,如上所示。 p>

【问题讨论】:

  • 设置Window半透明或组件时是否会出现这种情况? JDK 版本是什么?
  • @prunge 正如我在上一句中所说,它只是组件。窗口半透明效果完美。我正在测试 JDK 1.7_1 和 JDK 1.6_29
  • 你不只是在寻找 JComponent#setOpaque(false) 吗?您发布的代码毫无意义(尝试将其绘制为透明一次不会持久)
  • @WalterLaan 你知道JComponent#setOpaque(boolean b) 做什么吗?那不是我想要的。我想要整个组件的半透明,而不是背景的开/关。
  • 如果背景的任何部分必须显示给您的组件,那么您的组件必须将 opaque 设置为 false。所以是的,这就是你想要的。

标签: java swing awt transparency


【解决方案1】:

啊,你可能想看看 JLayer(或

tutorial

【讨论】:

  • 太好了,我可能最终会使用类似的东西。但是,它并没有回答我的问题。
【解决方案2】:

好吧,这是你的第一个问题:

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 版本成功,它将使函数短路。

【讨论】:

  • A:我不认为我可以静态更改任意组件的paint 方法。如果可以,请告诉我怎么做。 B:首先,NoSuchMethodError 并不“简单”,我之所以能抓住它是因为 Window#setOpacity(float f) 在小于 7 的 JRE 中不存在,所以我不必打印堆栈,因为我知道发生了什么并且下一个要运行的代码将适用于 JRE 6.u C:我检查了 Javadocs,我承认你的智慧。但是,我认为他们的意思是将其设置为不透明是整个解决方案
  • @Supuhstar:所以你不控制你想要半透明的组件?我认为这是您自己的组件,您试图使其半透明。在任何情况下,您都可以将每个想要半透明的组件包装在另一个确实了解半透明的组件中,并在那里使用 alpha 混合。
  • @Supuhstar:NoSuchMethodError 有什么不简单的? try { doSomething17Specific(); } catch (NoSuchMethodError e) { doSomething16Specific(); } 应该为您解决问题。
  • 不是处理不简单,而是导致它发生的原因。与Error 的所有扩展一样,NoSuchMethodError 意味着编译后的代码与现有库不匹配,并且无法执行。这不像IndexOutOfBoundsException 那样简单的修复
  • 我的意思是,你仍然可以用一个简单的catch (NoSuchMethodError e)捕捉它,而不是你精心设计的(而且速度很慢)getClass().isInstance(new NoSuchMethodError())。抓到它之后你实际上做了什么是一个完全不同的问题。
猜你喜欢
  • 2011-06-26
  • 1970-01-01
  • 2010-10-08
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 2021-01-19
  • 2011-08-31
相关资源
最近更新 更多