【问题标题】:Graphics2D not clearing transparent imageGraphics2D 不清除透明图像
【发布时间】:2012-05-02 01:56:13
【问题描述】:

我有以下 sn-p 代码,应该在第一台显示器的透明背景上增加一个计数器。当图像显示为 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();
    }
}

【问题讨论】:

    标签: java transparency repaint


    【解决方案1】:

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

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

    paintComponent() 方法开始,然后使用fillRect(),成功了!

    【讨论】:

    • 太奇怪了,该解决方案适用于 Windows,但不适用于 Ubuntu。 :(
    【解决方案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 表示颜色完全 透明的。

    【讨论】:

    • 再次尝试我的解决方案。它与您最初的问题相似,但它对我清除 BufferedImage 很有用。
    • 谢谢,+1 似乎确实有效 - 尽管我已经以另一种方式解决了它(请参阅下面的答案。)
    【解决方案3】:

    我知道这有点老了,但是你为什么不直接使用 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);
    }
    

    这应该会给你留下一个完全空白的图形对象来绘制。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 感谢您的回答,不幸的是 fillRect 不起作用 - 请参阅编辑。
      猜你喜欢
      • 1970-01-01
      • 2014-05-08
      • 2016-04-13
      • 2013-02-10
      • 2013-05-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 1970-01-01
      相关资源
      最近更新 更多