在Java2D中,当您使用setOpaque时,我对true和false的含义有点困惑。
例如,我知道在Swing中Opaque意味着当绘制时,Swing不会绘制组件后面的内容。或者是相反的吗?哪个是正确的?
谢谢
例如,我知道在Swing中Opaque意味着当绘制时,Swing不会绘制组件后面的内容。或者是相反的吗?哪个是正确的?
谢谢
isOpaque
是Swing系统与特定组件之间的契约。如果它返回true,则该组件保证以非半透明方式绘制其矩形区域的每个像素。这个API应该已经抽象化了,以迫使所有组件编写者考虑它。对于覆盖它并在其后面的组件(包括容器和祖先)来说,Swing的绘画系统使用isOpaque
API来确定是否必须绘制给定组件覆盖的区域。如果组件对此API返回true,则Swing系统可以对绘画进行优化,直到调用特定组件的paint方法为止,不需要在该区域内绘制任何内容。isOpaque
的契约意义,API setOpaque
不应存在,因为对于任何外部调用setOpaque
实际上是不正确的,因为外部无法知道涉及的组件是否会(甚至是否可以)遵守该设置。相反,isOpaque应被每个具体组件覆盖以返回它是否实际上是不透明的,考虑其当前属性。setOpaque
API确实存在,许多组件已经错误地实现了它(可以理解),以驱动它们是否将“背景”绘制(例如JLabel和JPanel填充其背景颜色)。这样做的效果是给API用户留下印象,即setOpaque
驱动是否应该绘制该背景,但实际上并非如此。此外,如果你想要给一个JLabel控件设置半透明背景,你需要设置一个带有alpha值的背景颜色,并且调用setOpaque(true)
方法,但它实际上并不是完全不透明的,而是半透明的;它后面的组件仍然需要被绘制才能使组件正确显示。因此,总的来说,你不应该使用这是Swing的原始设计问题,这个问题已经混淆了很多年。问题是setOpaque(false)在现有LAFs中具有隐藏背景的副作用,而这并不是它的真正意图。它的真正意图是表明组件可能有透明部分,Swing应该绘制其后面的父组件。
setOpaque
方法。如果你确实要使用它,请记住有些外观和一些组件的组合可能会做出“惊奇”的事情。最后,实际上并没有正确答案。javadoc说: 如果为真,组件将绘制其边界内的每个像素。否则,该组件可能不会绘制某些或所有像素,允许底层像素透过显示。
也可以尝试这个例子程序... http://www.java2s.com/Code/JavaAPI/javax.swing/JPanelsetOpaquebooleanisOpaque.htm
我认为还需要添加以下内容:
opaque这个术语在Java 2D和Swing中有不同的含义。
在Java 2D中,不透明度是一种渲染概念。它是alpha值和Composite
模式的组合。它是正在绘制的像素颜色应与已经存在的像素值混合的程度。例如,我们在现有的椭圆形上绘制一个半透明矩形。因此,椭圆形部分可见。这个概念经常被比作光线穿过玻璃或水。
在Swing中,不透明组件会绘制其矩形边界内的每个像素。非不透明组件只绘制其部分像素或根本不绘制,从而允许其下方的像素显示出来。设置不透明属性是为了提高效率;Swing不必绘制不透明组件后面的区域。
来源: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 不透明度");
JLabel lbl2 = new JLabel("Swing 不透明");
DrawingPanel dpanel = new DrawingPanel();
MyLabel mylbl = new MyLabel("isOpaque()");
mylbl.setBackground(Color.decode("#A9A9A9"));
createLayout(lbl1, lbl2, dpanel, mylbl);
setTitle("不透明");
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()
方法来设置一个灰色背景。
setPaintBackground(boolean)
的形式......或者将参数更改为从0到1的浮点因子,以设置不透明度的程度......0
表示透明,1
表示完全不透明。 - WesternGun