Graphics2D没有清除透明图像

时间:2012-05-02 01:56:14

标签: java transparency repaint

我有以下代码片段,应该在第一台显示器上的透明背景上增加一个计数器。当图像显示为0时,它呈现正常,但在此之后(一旦命中1),窗口将重绘不透明的背景。

实践中的愚蠢示例我知道,只是将一个真实的用例分解为更简单的代码。

似乎关键可能在TestCanvas的paintComponent方法中:

g.setColor(new Color(0, 0, 0, 0));
g.clearRect(0, 0, getWidth(), getHeight());

从我可以解决的问题来看,这两行应该将绘图颜色设置为完全透明,然后使用该颜色清除给定区域 - 但这似乎不会超出第一次重绘。

编辑:使用fillRect而不是clearRect不起作用,因为它只是在现有图像的顶部绘制透明矩形,因此它永远不会被清除。 1覆盖在0上,然后2覆盖在1等上

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;

public class LyricWindow extends JWindow {

    private final TestCanvas canvas;

    public LyricWindow(Rectangle area, boolean stageView) {
        setBackground(new Color(0, 0, 0, 0));
        setArea(area);
        canvas = new TestCanvas();
        canvas.setPreferredSize(new Dimension((int) (area.getMaxX() - area.getMinX()), (int) (area.getMaxY() - area.getMinY())));
        add(canvas);
        new Thread() {

            public void run() {
                for(int i = 0; true; i++) {
                    final int ii = i;
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            canvas.setText(Integer.toString(ii));
                        }
                    });
                    try {
                        Thread.currentThread().sleep(200);
                    }
                    catch(InterruptedException ex) {}
                    System.out.println(ii);
                }
            }
        }.start();
    }

    public final void setArea(final Rectangle area) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                if(canvas != null) {
                    canvas.setPreferredSize(new Dimension((int) (area.getMaxX() - area.getMinX()), (int) (area.getMaxY() - area.getMinY())));
                }
                setSize((int) (area.getMaxX() - area.getMinX()), (int) (area.getMaxY() - area.getMinY()));
                setLocation((int) area.getMinX(), (int) area.getMinY());
            }
        });
    }

    public static void main(String[] args) {
        LyricWindow w = new LyricWindow(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getConfigurations()[0].getBounds(), false);
        w.setVisible(true);
    }
}

class TestCanvas extends JPanel {

    private String text;

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(new Color(0, 0, 0, 0));
        g.clearRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.RED);
        g.drawString(text, 100, 100);
    }

    public void setText(String s) {
        text = s;
        repaint();
    }
}

4 个答案:

答案 0 :(得分:3)

原来我必须在绘画前设置正确的复合值。添加

((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));

paintComponent()方法的开头,然后使用fillRect(),就可以了!#/ p>

答案 1 :(得分:2)

尝试g.fillRect(...)而不是g.clearRect(...)。我想我遇到过一次类似的问题,这可能已经为我解决了。

我找到了问题的原始解决方案,可用于BufferedImages。不知道为什么白色可能会起作用而黑色不会,但试一试:

g.setBackground(new Color(255, 255, 255, 0));
g.clearRect(0, 0, width, height);

来自Color班的Javadoc:

  

Alpha值为1.0或255表示颜色完全不透明   并且alpha值为0或0.0表示颜色是完全的   透明的。

答案 2 :(得分:0)

如果你的颜色是完全透明的,清除实际上是做什么的吗?

尝试将alpha值设置为255,而不是0.问题是,这会将矩形“清除”为黑色(0, 0, 0),但我不确定是否可以将其“清除”为透明{ {1}}。您可以尝试使用clearRect

答案 3 :(得分:0)

我知道这有点旧了,但是你为什么不通过调用超类中的函数来使用JPanel已经构建的功能来清除画布?

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(new Color(0, 0, 0, 0));
    g.clearRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.RED);
    g.drawString(text, 100, 100);
}

这应该让你有一个完全空白的图形对象来绘制。