2

私は最近、半透明のコンポーネントが適切に更新されていないように見えることから奇妙なアーティファクトを引き起こしていることについて質問しました。私が受け取った答えにより、アーティファクトは消えましたが、半透明性が犠牲になりました。

解決策は、すべての半透明のコンポーネントに対して、setOpaque(false)関数も呼び出すことでした。このようにして、Swingは、これらのコンポーネントの背後にある背景を再描画する必要があることを認識していました。

しかし、これは私が達成しようとしていた半透明性を犠牲にしてもたらされました。代わりに、コンポーネントが透明になりました。

前提は次のとおりです。チャットクライアント用のGUIを設計しており、機能要求にはバックグラウンドが必要でした。JPanelクラスを拡張するためのコードスニペットに従うことでバックグラウンドを正常に機能させることができましたが、コンポーネントでバックグラウンドを表示できるようにする必要がありました。半透明を設定した後、更新されたコンポーネントの残骸が本来あるべき場所に表示されていました。私はここに来て問題を解決しましたが、今は新しい問題があります。だからここにいます。

だから、これが私が推測したことです:

-目的のコンポーネントごとにsetOpaque(false)関数を呼び出し、半透明の色を設定しないと、目的の結果が得られません。

-半透明の色を設定し、setOpaque(false)を呼び出さないことで、半透明の背景を表示できますが、アーティファクトが発生し、正方形に戻ります。

したがって、アーティファクトのない透明とアーティファクトのある半透明の中間点が必要です。つまり、アーティファクトのない半透明の背景(完全に透明ではない)が必要です。

不透明度に関係なく、JFrameをオーバーライドして、すべてのコンポーネントを再描画する必要があるようです。私が欠けているものがない限り..それが私がここにいる理由です!

ありがとう!

(元の質問へのリンクと、参照用の画像があります:Java Swing-アーティファクトの原因となる半透明のコンポーネント

4

1 に答える 1

4

1つのオプションは、コンポーネントをオーバーライドして、自分で背景を描画することです。

class TranslucentLabel extends JLabel {
    public TranslucentLabel(String text) {
        super(text);
        setOpaque(false);
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(new Color(255, 0, 0, 64));
        Insets insets = getInsets();
        g.fillRect(insets.left, insets.top, 
                getWidth() - insets.left - insets.right, 
                getHeight() - insets.top - insets.bottom);
        super.paintComponent(g);
    }
}

編集:あるいは、子コンポーネントの半透明の背景色をパネルに直接描画することもできます。そうすれば、コンポーネントをオーバーライドする必要はありません。

class YourPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g.create();

        // Draw your background image here to g2d.

        g2d.setColor(new Color(255, 0, 0, 64));
        Area area = new Area();
        for (Component component : getComponents()) {
            area.add(new Area(component.getBounds()));
        }
        g2d.fill(area);
        g2d.dispose();
    }
}

このアプローチには欠点があります。コンポーネントの真に透明な部分(丸みを帯びた境界線など)がある場合、その背景全体が色付けされます。

于 2011-02-13T10:47:56.330 に答える