java - 如果 `set setOpaque(false);`,JWindow 上的 JPanel 不透明 - 为什么?

标签 java swing jpanel transparency jwindow

如何让JPanel在这个例子中变得透明?渐变背景不可见:

package test;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;

public class PaintJPanelOnJWindow extends JWindow {

    public PaintJPanelOnJWindow() {

        JPanel panel = new JPanel();

        panel.setPreferredSize(new Dimension(350, 120));
        panel.setMinimumSize(new Dimension(350, 120));
        panel.setMaximumSize(new Dimension(350, 120));

        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setOpaque(false);

        JLabel someText = new JLabel("I'm not transparent and my JPanel too :(");
        someText.setOpaque(false);
        panel.add(someText);
        add(panel);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {

        Graphics2D g2d = (Graphics2D) g.create();
        try {
            int w = getWidth(), h = getHeight();
            g2d.setPaint(new GradientPaint(0, 0, Color.RED, 0, h, Color.WHITE));
            g2d.fillRect(0, 0, w, h);
        } finally {
            g2d.dispose();
        }
        super.paint(g);
    }
}

最佳答案

当前的问题是

super.paint(g);

paint 方法中的自定义绘制代码之后被调用,这将导致任何先前的绘制丢失。调用 panel.setOpaque(false) 不会影响 paint 方法中所做的操作。无需为问题中的任何组件调用 setOpaque - 默认情况下,正确实现自定义绘制时会显示背景。

这应该通过覆盖 paintComponent 来完成方法。这意味着创建一个新的 JPanel 并将自定义绘画功能放置在其中,而不是放置在 JWindow 等顶级容器中。

示例:

enter image description here

public class PaintJPanelApp {


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Gradient App");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setUndecorated(true);
                frame.setLocationRelativeTo(null);

                JLabel someText = new JLabel("I AM transparent and my JPanel too :)");
                GradientPanel gradientPanel = new GradientPanel();
                gradientPanel.add(someText);
                frame.add(gradientPanel);

                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    static class GradientPanel extends JPanel {


        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int w = getWidth(); 
            int h = getHeight();
            Graphics2D g2d = (Graphics2D) g;
            g2d.setPaint(new GradientPaint(0, 0, Color.RED, 0, h, Color.WHITE));
            g2d.fillRect(0, 0, w, h);
        }
    }
}

关于java - 如果 `set setOpaque(false);`,JWindow 上的 JPanel 不透明 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18262624/

相关文章:

java - 如何从 JPanel 触发 ActionEvent

java - 多线程和 Swing

java - 如何在绘制 JPanel 后重新绘制它?

java - 使用 BoxLayout 时 JPanel 不居中

java - 观察者模式和有状态的可观察范式

Java - 如何将文件拖放到 JTextArea 上

java - 获取JFrame当前所在显示器的屏幕设备信息

java - 如何用新的散点更新绘图区域?

java - 将构造函数隐藏在包之外

java - 在 App Engine 上添加安全提供程序时出现 AccessControlException