3

最初のモニターの透明な背景でカウンターをインクリメントするのコード スニペットがあります。画像に 0 が表示されると正常にレンダリングされますが、その後 (1 がヒットするとすぐに) ウィンドウは不透明な背景で再描画されます。

私が知っている実際のばかげた例は、実際のユースケースをより単純なコードに分解しただけです。

鍵は TestCanvas の paintComponent メソッドにあるようです:

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

私が理解できることから、これらの2行は描画色を完全に透明に設定し、次にその色で指定された領域をクリアする必要があります-しかし、これは最初の再描画を超えて保持されていないようです.

編集: clearRect の代わりに fillRect を使用しても機能しません。これは、既存の画像の上に透明な四角形をペイントするだけであり、クリアされることはありません。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

4 に答える 4

4

ペイントする前に正しい複合値を設定する必要があることがわかりました。追加する

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

paintComponent()メソッドの開始まで、次に を使用するfillRect()と、うまくいきました!

于 2012-05-02T11:09:26.683 に答える
3

g.clearRect(...) の代わりに g.fillRect(...) を試してください。私はかつて同様の問題に遭遇したと思いますが、これで解決したかもしれません。

で使用するための問題に対する独自の解決策を見つけましたBufferedImages。白が機能するのに黒が機能しない理由はわかりませんが、試してみてください。

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

Colorクラスの Javadocから:

アルファ値 1.0 または 255 は色が完全に不透明であることを意味し、アルファ値 0 または 0.0 は色が完全に透明であることを意味します。

于 2012-05-02T02:02:57.083 に答える
0

あなたの色が完全に透明な場合、クリアは実際に何かをしますか?

アルファ値を 0 ではなく 255 に設定してみてください。問題は、長方形を black(0, 0, 0)に「クリア」することですが、 で透明に「クリア」できるかどうかはわかりませんclearRectfillRect代わりに試すことができます。

于 2012-05-02T02:04:05.933 に答える