清理图形清理所有图形

Cleaning the graphics clean all the graphics

我的 Java 图形有点问题,我有我的特殊 JComponent,一个纹理按钮。当鼠标打开时,按钮变得有点亮(它被半透明的白色填充),但图形不干净,所以透明白色在组件上形成全白背景,即使鼠标是不在按钮上。它看起来像这样:

所以我找到了解决方案,我添加了这个:

super.paintComponent(g);

// Clearing
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
g.setColor(Swinger.TRANSPARENT);
g.fillRect(0, 0, this.getWidth(), this.getHeight());

在我的组件 paintComponent 方法上,它成功了!但是,它不仅清除了按钮背景,还清除了它后面的所有内容!没有按钮看起来像这样:

并使用按钮:

后台可以看到IDEA

这是我的代码(参见 fr.theshark34.swinger.textured.STexturedButton class): https://github.com/TheShark34/Swinger

您似乎对Swing中的绘画工作原理缺乏了解或误解,无论哪种情况,都有些可怕。

您可能想仔细查看 Painting in AWT and Swing and Performing Custom Painting 以了解有关 Swing 绘画工作原理的更多详细信息

在你的 STexturedButton class 中,你不需要做...

((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
g.setColor(Swinger.TRANSPARENT);
g.fillRect(0, 0, this.getWidth(), this.getHeight());

因为 Swing 已经(基本上)为您完成了(因为 STexturedButton 从您的 AbstractButton class 延伸,它从 JComponent 延伸,这是透明的默认情况下,如果组件不是透明的,则执行您所做的操作将很危险,并且会以额外奇怪的油漆人工制品结束。

所以在我的测试中,我只是把它拿出来了。

此外,我更愿意重写 getPreferredSize 而不是提供您自己的 setBounds 方法,一开始它很混乱(因为组件已经有自己的 setBounds 方法并使用 getPreferredSize 与现有的 Swing API)

配合得很好

由于您没有提供任何类型的可运行示例,我不得不自己制作,但这些更改对我来说效果很好。

import fr.theshark34.swinger.textured.STexturedButton;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());

            try {
                STexturedButton btn = new STexturedButton(ImageIO.read(getClass().getResource("/Pony.png")));
                add(btn);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            LinearGradientPaint lgp = new LinearGradientPaint(
                    new Point(0, 0),
                    new Point(0, getHeight()),
                    new float[]{
                        0.1428571428571429f,
                        0.2857142857142858f,
                        0.4285714285714287f,
                        0.5714285714285716f,
                        0.7142857142857145f,
                        0.8571428571428574f,
                        1f
                    },
                    new Color[]{Color.RED, Color.ORANGE, Color.GREEN, Color.YELLOW, Color.BLUE, Color.MAGENTA, Color.PINK}
            );
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setPaint(lgp);
            g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
            g2d.dispose();
        }

    }

}

现在有一个工作透明的 window 示例

import fr.theshark34.swinger.textured.STexturedButton;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setUndecorated(true);
                frame.setBackground(new Color(0, 0, 0, 0));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            setOpaque(false);

            try {
                STexturedButton btn = new STexturedButton(ImageIO.read(getClass().getResource("/Pony.png")));
                add(btn);
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setBorder(new LineBorder(Color.RED));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}