如何设置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.fillRoundRect
和g2d.drawRoundRect
弄乱JPanel形状,但它不在这个问题的范围内。