setOpaque(真/假); Java的

在Java2D中,当你使用setOpaque时,我对true和false的作用有点困惑。

例如,我知道在Swing Opaque中意味着在绘制Swing时不会绘制组件背后的内容。 或者这是倒退? 哪一个?

谢谢

对你的问题的简短回答是,“不透明”在英语中定义为完全不透明。 因此,不透明的组件是绘制整个矩形的组件,并且每个像素在任何程度上都不是半透明的。

但是,Swing组件opacity API是那些设计错误的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和透明文本字段 )。 Nimbus开发团队的反应如下:

这是Swing的原始设计中的一个问题,以及它多年来一直令人困惑的问题。 问题是setOpaque(false)在[现有] LAF中产生了一个副作用,即隐藏背景而不是它的意思。 这意味着组件可能具有透明部分,[Swing]应该在其后面绘制父组件。

因此,总之,您不应该使用setOpaque 。 如果您确实使用它,请记住,一些外观和感觉以及某些组件的组合可能会“令人惊讶”。 最后,实际上没有正确的答案。

javadoc说: 如果为true,则组件绘制其边界内的每个像素。 否则,组件可能不会绘制其部分或全部像素, 从而允许底层像素显示。

尝试这个示例程序… http://www.java2s.com/Code/JavaAPI/javax.swing/JPanelsetOpaquebooleanisOpaque.htm

我认为还需要添加以下内容:

术语opaque在Java 2D和Swing中具有不同的含义。

在Java 2D中,不透明度是一种渲染概念。 它是alpha值和Composite模式的Composite 。 它是被绘制的像素颜色应该与已经存在的像素值混合的程度。 例如,我们在现有的椭圆形上绘制一个半透明的矩形。 因此椭圆形部分可见。 这种概念通常与透光玻璃或水相比较。

在Swing中,不透明组件绘制其矩形边界内的每个像素。 非不透明组件仅绘制其像素的子集或根本不绘制,允许其下方的像素显示。 不透明的属性是出于效率原因而设定的; Swing不必在不透明组件后面绘制区域。

资料来源:Java docs和Filthy Rich Clients

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); } }); } }
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()方法来设置灰色背景。

不透明的解释说