Java 如何设置JPanel的透明背景?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2545214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:07:17  来源:igfitidea点击:

How to set a transparent background of JPanel?

javaswinggraphicsbackgroundjpanel

提问by Imran

Can JPanels background be set to transparent?

JPanel的背景设置为透明?

My frame is has two JPanels:

我的框架有两个JPanel

  • Image Paneland
  • Feature Panel.
  • 图像面板
  • 功能面板

Feature Panelis overlapping Image Panel. The Image Panelis working as a background and it loads image from a remote URL.

Feature PanelImage Panel重叠。所述图像面板正在作为后台和它从远程URL加载图像。

On Feature PanelI want to draw shapes. Now Image Panelcannot be seen due to Feature Panel'sbackground color.

功能面板上我想绘制形状。由于功能面板的背景颜色,现在无法看到图像面板

I need to make Feature Panelbackground transparent while still drawing its shapes and I want Image Panelto be visible (since it is doing tiling and cache function of images).

我需要在绘制其形状的同时使功能面板背景透明,并且我希望图像面板可见(因为它正在执行图像的平铺和缓存功能)。

I'm using two JPanel's, because I need to seperate the image and shape drawing .

我使用的是两个JPanel,因为我需要将图像和形状绘图分开。

Is there a way the overlapping Jpanel have a transparent background?

重叠的 Jpanel 有没有透明背景的方法?

采纳答案by trashgod

Alternatively, consider The Glass Pane, discussed in the article How to Use Root Panes. You could draw your "Feature" content in the glass pane's paintComponent()method.

或者,考虑在文章如何使用根窗格中讨论的玻璃窗格。您可以在玻璃窗格的方法中绘制“功能”内容。paintComponent()

Addendum: Working with the GlassPaneDemo, I added an image:

附录:使用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);

and altered the glass pane's paintComponent()method:

并改变了玻璃窗格的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

在此处输入图片说明

As noted here, Swing components must honor the opaque property; in this variation, the ImageIconcompletely fills the BorderLayout.CENTERof the frame's default layout.

如前所述这里,Swing组件必须履行的不透明财产; 在这个变体中,ImageIcon完全填充BorderLayout.CENTER了框架的默认布局。

回答by Nate

Calling setOpaque(false)on the upper JPanelshould work.

呼叫setOpaque(false)上层JPanel应该有效。

From your comment, it sounds like Swing painting may be broken somewhere -

从您的评论来看,Swing 绘画可能在某处损坏了-

First - you probably wanted to override paintComponent()rather than paint()in whatever component you have paint()overridden in.

首先 - 您可能想要覆盖paintComponent()而不是paint()在您paint()覆盖的任何组件中。

Second - when you do override paintComponent(), you'll first want to call super.paintComponent()first to do all the default Swing painting stuff (of which honoring setOpaque()is one).

其次 - 当您执行 override 时paintComponent(),您首先要先调用super.paintComponent()以执行所有默认的 Swing 绘画(其中 HonoringsetOpaque()是其中之一)。

Example -

例子 -

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);
        }
    }
}

回答by Imran

 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);
     } 

I have tried to do it this way, but it is very flickery

我试过这样做,但它非常闪烁

回答by Edesa

(Feature Panel).setOpaque(false);

Hope this helps.

希望这可以帮助。

回答by Ordiel

In my particular case it was easier to do this:

在我的特殊情况下,这样做更容易:

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

回答by emportella

As Thrasgodcorrectly showed in his answer, the best way is to use the paintComponent, but also if the case is to have a semi transparent JPanel (or any other component, really) and have something not transparent inside. You have to also override the paintChildren method and set the alfa value to 1. In my case I extended the JPanel like that:

正如Thrasgod在他的回答中正确显示的那样,最好的方法是使用paintComponent,但如果情况是有一个半透明的 JPanel(或任何其他组件,真的)并且里面有一些不透明的东西。您还必须覆盖paintChildren 方法并将alfa 值设置为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
}

And in my project I only need to instantiate Jpanel jp = new TransparentJPanel(0.3f, 1.0f);, if I want only the Jpanel transparent. You could, also, mess with the JPanel shape using g2d.fillRoundRectand g2d.drawRoundRect, but it's not in the scope of this question.

在我的项目中Jpanel jp = new TransparentJPanel(0.3f, 1.0f);,如果我只想要 Jpanel 透明,我只需要实例化。您也可以使用g2d.fillRoundRectand弄乱 JPanel 形状g2d.drawRoundRect,但这不在此问题的范围内。

回答by Shrinivasan

To set transparent you can set opaque of panel to false like

要设置透明,您可以将面板的不透明设置为 false,例如

   JPanel panel = new JPanel();
   panel.setOpaque(false);

But to make it transculent use alpha property of color attribute like

但是要使其半透明,请使用颜色属性的 alpha 属性,例如

   JPanel panel = new JPanel();
   panel.setBackground(new Color(0,0,0,125));

where last parameter of Color is for alpha and alpha value ranges between 0 and 255 where 0 is full transparent and 255 is fully opaque

其中 Color 的最后一个参数用于 alpha 和 alpha 值范围在 0 到 255 之间,其中 0 是完全透明的,255 是完全不透明的