web-dev-qa-db-ja.com

JPanelの透明な背景を設定する方法は?

JPanels背景を透明に設定できますか?

私のフレームには2つのJPanelsがあります:

  • 画像パネルおよび
  • 機能パネル

機能パネルが重なっています画像パネル画像パネルは背景として機能し、リモートURLから画像をロードします。

オン機能パネル図形を描きたい。 画像パネルは、機能パネルの背景色のために見ることができません。

形状パネル背景を透明にしながら、その形状を描画する必要があります画像パネル(画像のタイリングとキャッシュ機能を実行しているため)表示されます。

2つのJPanelを使用しています。これは、画像と図形の描画を分離する必要があるためです。

重複するJpanelの背景が透明になる方法はありますか?

25
Imran

あるいは、記事で説明されている The Glass Pane を検討してください Howルートペインを使用するには ガラスペインのpaintComponent()メソッドに「機能」コンテンツを描画できます。

補遺: GlassPaneDemo の操作、画像を追加しました:

_//Set up the content pane, where the "main GUI" lives.
frame.add(changeButton, BorderLayout.SOUTH);
frame.add(new JLabel(new ImageIcon("img.jpg")), BorderLayout.CENTER);
_

ガラスペインのpaintComponent()メソッドを変更しました。

_protected void paintComponent(Graphics g) {
    if (point != null) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setComposite(AlphaComposite.getInstance(
            AlphaComposite.SRC_OVER, 0.3f));
        g2d.setColor(Color.yellow);
        g2d.fillOval(point.x, point.y, 120, 60);
    }
}
_

enter image description here

前述のとおり、 here 、Swingコンポーネントは opaqueプロパティ を順守する必要があります。このバリエーションでは、ImageIconはフレームのデフォルトレイアウトの_BorderLayout.CENTER_を完全に埋めます。

7
trashgod

上のJPanelsetOpaque(false)を呼び出すと動作するはずです。

あなたのコメントから、Swingペインティングがどこかで壊れているようです。

最初に-paintComponent()がオーバーライドされているコンポーネントでは、Paint()ではなくPaint()をオーバーライドしたいでしょう。

2番目-paintComponent()をオーバーライドする場合、最初にsuper.paintComponent()を呼び出して、すべてのデフォルトのSwingペインティング処理を行います(setOpaque()を尊重することは1つです)。

例-

import Java.awt.Color;
import Java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class TwoPanels {
    public static void main(String[] args) {

        JPanel p = new JPanel();
        // setting layout to null so we can make panels overlap
        p.setLayout(null);

        CirclePanel topPanel = new CirclePanel();
        // drawing should be in blue
        topPanel.setForeground(Color.blue);
        // background should be black, except it's not opaque, so 
        // background will not be drawn
        topPanel.setBackground(Color.black);
        // set opaque to false - background not drawn
        topPanel.setOpaque(false);
        topPanel.setBounds(50, 50, 100, 100);
        // add topPanel - components Paint in order added, 
        // so add topPanel first
        p.add(topPanel);

        CirclePanel bottomPanel = new CirclePanel();
        // drawing in green
        bottomPanel.setForeground(Color.green);
        // background in cyan
        bottomPanel.setBackground(Color.cyan);
        // and it will show this time, because opaque is true
        bottomPanel.setOpaque(true);
        bottomPanel.setBounds(30, 30, 100, 100);
        // add bottomPanel last...
        p.add(bottomPanel);

        // frame handling code...
        JFrame f = new JFrame("Two Panels");
        f.setContentPane(p);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300, 300);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    // Panel with a circle drawn on it.
    private static class CirclePanel extends JPanel {

        // This is Swing, so override Paint*Component* - not Paint
        protected void paintComponent(Graphics g) {
            // call super.paintComponent to get default Swing 
            // painting behavior (opaque honored, etc.)
            super.paintComponent(g);
            int x = 10;
            int y = 10;
            int width = getWidth() - 20;
            int height = getHeight() - 20;
            g.drawArc(x, y, width, height, 0, 360);
        }
    }
}
27
Nate

私の特定のケースでは、これを行う方が簡単でした:

 panel.setOpaque(true);
 panel.setBackground(new Color(0,0,0,0,)): // any color with alpha 0 (in this case the color is black
8
Ordiel
(Feature Panel).setOpaque(false);

お役に立てれば。

4
Edesa
 public void paintComponent (Graphics g)
    { 
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.0f)); // draw transparent background
     super.paintComponent(g);
    ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f)); // turn on opacity
    g.setColor(Color.RED);
    g.fillRect(20, 20, 500, 300);
     } 

私はこのようにしようとしましたが、それは非常にちらつきです

2
Imran

Thrasgod の答えに正しく示されているように、最良の方法はpaintComponentを使用することですが、ケースが半透明のJPanel(または他のコンポーネント)を持ち、内部に透明でないものがある場合も。また、paintChildrenメソッドをオーバーライドし、アルファ値を1に設定する必要があります。私の場合、JPanelを次のように拡張しました。

_public class TransparentJPanel extends JPanel {

private float panelAlfa;
private float childrenAlfa;

public TransparentJPanel(float panelAlfa, float childrenAlfa) {
    this.panelAlfa = panelAlfa;
    this.childrenAlfa = childrenAlfa;
}

@Override
public void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(getBackground());
    g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setComposite(AlphaComposite.getInstance(
            AlphaComposite.SRC_OVER, panelAlfa));
    super.paintComponent(g2d);

}

@Override
protected void paintChildren(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(getBackground());
    g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setComposite(AlphaComposite.getInstance(
            AlphaComposite.SRC_ATOP, childrenAlfa));

    super.paintChildren(g); 
}
 //getter and setter
}
_

私のプロジェクトでは、Jpanelのみを透明にする場合は、Jpanel jp = new TransparentJPanel(0.3f, 1.0f);をインスタンス化するだけです。また、_g2d.fillRoundRect_および_g2d.drawRoundRect_を使用してJPanelシェイプを台無しにすることもできますが、この質問の範囲には含まれていません。

1
emportella