有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

swing Set不透明(真/假);JAVA

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

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

谢谢


共 (3) 个答案

  1. # 1 楼答案

    我认为还需要补充以下内容:

    术语不透明在Java2D和Swing中有不同的含义

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

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

    Opaque explained

  2. # 2 楼答案

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

    然而,Swing组件不透明API是设计错误的API之一,因此经常被错误使用

    重要的是要理解isOpaque是Swing系统和特定组件之间的契约。如果像素的每个区域都是非半透明的,则它将保证其矩形区域返回为true。这个API 应该是抽象的,强迫所有的编写者考虑它。Swing的绘制系统使用isOpaqueAPI来确定给定组件覆盖的区域是否必须为重叠的组件和位于其后面的组件(包括组件的容器和祖先)绘制。如果组件对此API返回true,Swing系统可能会优化绘制,以在调用特定组件的绘制方法之前不在该区域绘制任何内容

    由于isOpaque的合同含义,API setOpaque不应该存在,因为任何外部调用setOpaque实际上都是不正确的,因为反过来,外部事物不知道所讨论的组件是否会(甚至可以)遵守它。相反,每个混凝土构件都应该覆盖isOpaque,以返回它在给定其当前属性的情况下是否实际上是不透明的

    由于setOpaqueAPI确实存在,许多组件错误地实现了它(可以理解),以驱动它们是否绘制“背景”(例如,JLabel和JPanel用背景色填充)。这样做的效果是让API的用户产生一种印象,认为setOpaque决定了背景是否应该绘制,但事实并非如此

    此外,如果您希望使用半透明背景绘制JLabel,则需要使用alpha值设置背景颜色,并执行setOpaque(true),但实际上它不是不透明的-它是半透明的;它后面的组件仍然需要绘制,以便组件正确渲染

    这个问题在Java6的新Nimbus外观&;感觉有许多关于针对Nimbus的透明组件的bug报告(请参阅堆栈溢出问题Java Nimbus LAF with transparent text fields)。Nimbus开发团队的反应是:

    This is a problem [in] the orginal design of Swing and how it has been confusing for years. The issue is setOpaque(false) has had a side effect in [existing] LAFs which is that of hiding the background which is not really what it is [meant] for. It is [meant] to say that the component may have transparent parts and [Swing] should paint the parent component behind it.

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