如何设置JPanel的透明背景?

JPanel的背景可以设置为透明吗?

我的框架有两个JPanel

  • 图像面板
  • function面板

function面板图像面板重叠。 图像面板作为背景工作,它从远程URL加载图像。

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

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

我正在使用两个JPanel ,因为我需要分离图像和形状绘图。

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

或者,请考虑 如何使用根窗格 ”一文中讨论的“玻璃窗格” 。 您可以在玻璃窗格的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); } } 

在此处输入图像描述

如上所述,Swing组件必须遵守不透明属性 ; 在此变体中, ImageIcon完全填充框架默认布局的BorderLayout.CENTER

在上面的JPanel上调用setOpaque(false)应该可以工作。

从你的评论中,听起来像Swing绘画可能在某处被打破 –

首先 – 您可能希望覆盖paintComponent()而不是paint()在任何覆盖了paint()的组件中。

第二 – 当你覆盖paintComponent() ,你首先想要调用super.paintComponent()来做所有默认的Swing绘画(其中一个是尊重setOpaque()是一个)。

示例 –

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

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

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

希望这可以帮助。

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

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

正如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 } 

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