设置不透明(真/假);爪哇
Posted
技术标签:
【中文标题】设置不透明(真/假);爪哇【英文标题】:setOpaque(true/false); Java 【发布时间】:2011-01-27 23:05:57 【问题描述】:在 Java2D 中,当您使用 setOpaque 时,我对 true 和 false 的作用有点困惑。
例如,我知道在 Swing 中不透明意味着在绘制 Swing 时不会绘制组件后面的内容。或者这是倒退?是哪一个?
谢谢
【问题讨论】:
【参考方案1】:对您的问题的简短回答是,“不透明”在英语中被定义为完全不透明。因此,不透明组件是绘制整个矩形的组件,并且每个像素都不是半透明的。
然而,Swing 组件 opacity API 是设计错误的 API 之一,因此经常被误用。
重要的是要了解isOpaque
是Swing 系统和特定组件之间的契约。如果它返回 true,则组件保证不透明地绘制其矩形区域的每个像素。此 API应该 是抽象的,以强制所有组件编写者考虑它。 Swing 的绘制系统使用isOpaque
API 来确定是否必须为给定组件所覆盖的区域绘制与它重叠和在它后面的组件,包括组件的容器和祖先。如果组件向此 API 返回 true,则 Swing 系统可能会优化绘制,以便在调用特定组件的绘制方法之前不绘制该区域的任何内容。
由于isOpaque
的合同含义,API setOpaque
不应该存在,因为调用setOpaque
的外部事物实际上是不正确的,因为反过来,外部事物可以'不知道有问题的组件是否会(甚至可以)兑现它。相反,isOpaque 应该被每个具体组件覆盖,以返回它是否实际上是不透明的,事实上,给定其当前属性。
因为setOpaque
API确实存在,许多组件错误地实现了它(很容易理解)来决定它们是否会绘制它们的“背景”(例如 JLabel 和 JPanel 填充他们的背景颜色)。这样做的效果是让 API 的用户 产生一种印象,认为setOpaque
驱动该背景是否应该绘制,但事实并非如此。
此外,如果您希望绘制具有半透明背景的 JLabel,则需要设置具有 alpha 值的背景颜色,然后执行setOpaque(true)
,但它实际上并不是不透明的 - 它是半透明时间>;它后面的组件仍然需要绘制才能使组件正确呈现。
Java 6 的新 Nimbus Look & Feel 显着暴露了这个问题。有许多关于针对 Nimbus 提交的透明组件的错误报告(请参阅堆栈溢出问题 Java Nimbus LAF with transparent text fields)。 Nimbus 开发团队的回应是这样的:
这是 Swing 原始设计中的一个问题,并且多年来一直令人困惑。问题是 setOpaque(false) 在 [existing] LAF 中产生了副作用,即隐藏背景,而这并不是它 [意味着] 的真正用途。 [意思是]说组件可能有透明部分,[Swing]应该在它后面绘制父组件。
因此,总而言之,您不应该使用setOpaque
。如果您确实使用它,请记住某些外观和某些组件的组合可能会做“令人惊讶”的事情。而且,到最后,其实并没有正确的答案。
【讨论】:
迟到了,但感谢您解释 isOpaque 和 alpha 通道之间的关系。我被难住了,因为它们似乎覆盖了同一个区域——知道那是有帮助的,因为 isOpaque 是愚蠢的。 :) 应该将其更改为setPaintBackground(boolean)
....或将参数更改为从0到1的浮点因子,以设置不透明度......0
是透明的,1
完全不是。
@FaithReaper:该 API 必须被弃用,并用正确规范的东西和 protected
替换。【参考方案2】:
我觉得还需要补充以下几点:
不透明这个词在 Java 2D 和 Swing 中有不同的含义。
在 Java 2D 中,不透明度是一个渲染概念。这是一个组合
alpha 值和Composite
模式。这是一个学位
正在绘制的像素颜色应与像素混合
已经存在的值。例如,我们画一个半透明的
现有椭圆形上的矩形。因此椭圆形是
部分可见。这个概念经常被比作光
穿过玻璃或水。
在 Swing 中,一个不透明的组件绘制其内部的每个像素 矩形边界。一个不透明的组件只绘制一个子集 它的像素或根本没有,允许它下面的像素 通过展示。 opaque 属性是出于效率原因而设置的;摇摆 不必在不透明组件后面绘制区域。
来源:Java 文档和肮脏的富客户端
package com.zetcode;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import static javax.swing.SwingConstants.CENTER;
import net.miginfocom.swing.MigLayout;
class DrawingPanel extends JPanel
@Override
public void paintComponent(Graphics g)
super.paintComponent(g);
doDrawing(g);
private void doDrawing(Graphics g)
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.green);
g2d.fillOval(20, 20, 100, 100);
g2d.setColor(Color.blue);
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.1f));
g2d.fillRect(0, 0, 150, 150);
class MyLabel extends JLabel
public MyLabel(String text)
super(text, null, CENTER);
@Override
public boolean isOpaque()
return true;
public class OpaqueEx2 extends JFrame
public OpaqueEx2()
initUI();
private void initUI()
JLabel lbl1 = new JLabel("Java 2D opacity");
JLabel lbl2 = new JLabel("Swing opaque");
DrawingPanel dpanel = new DrawingPanel();
MyLabel mylbl = new MyLabel("isOpaque()");
mylbl.setBackground(Color.decode("#A9A9A9"));
createLayout(lbl1, lbl2, dpanel, mylbl);
setTitle("Opaque");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
private void createLayout(JComponent... arg)
JPanel pnl = new JPanel(new MigLayout("ins 10"));
pnl.add(arg[0], "w 150");
pnl.add(arg[1], "w 150, wrap");
pnl.add(arg[2], "w 150, h 150");
pnl.add(arg[3], "w 150, h 150");
add(pnl);
pack();
public static void main(String[] args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
OpaqueEx2 ex = new OpaqueEx2();
ex.setVisible(true);
);
在代码示例中,我们有两个组件。左边的组件是一个面板,它使用AlphaComposite
在椭圆上绘制一个高度半透明的矩形。右边的组件是一个标签。标签在大多数外观和感觉中都是不透明的。我们覆盖标签的isOpaque()
方法来设置灰色背景。
【讨论】:
【参考方案3】:javadoc 说:如果为 true,则组件绘制其边界内的每个像素。否则,组件可能不会绘制其部分或全部像素,允许底层像素显示出来。
也试试这个示例程序... http://www.java2s.com/Code/JavaAPI/javax.swing/JPanelsetOpaquebooleanisOpaque.htm
【讨论】:
如果为true,则不显示后面的组件.. 如果为false,则显示.. 我们不需要看javadoc,一本英文字典就足够了 :) :) : ) 是的,我就是这么想的,但是在阅读了很多东西之后,我感到很困惑。谢谢:)以上是关于设置不透明(真/假);爪哇的主要内容,如果未能解决你的问题,请参考以下文章
EXCEL函数。 如果A1等于1-50数据中的任何一个, 则A2返回“真”, 否则返回“假”, 如何设置函数。
为啥在 undertow 服务器中将端口设置为 80 失败? (爪哇)