How to set a transparent background of JPanel?

后端 未结 7 1730
栀梦
栀梦 2020-12-05 04:57

Can JPanels background be set to transparent?

My frame is has two JPanels:

  • Image Panel and
相关标签:
7条回答
  • 2020-12-05 05:11

    As Thrasgod correctly 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:

    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.fillRoundRect and g2d.drawRoundRect, but it's not in the scope of this question.

    0 讨论(0)
  • 2020-12-05 05:18
    (Feature Panel).setOpaque(false);
    

    Hope this helps.

    0 讨论(0)
  • 2020-12-05 05:24

    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
    
    0 讨论(0)
  • 2020-12-05 05:25

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

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

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

       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

    0 讨论(0)
  • 2020-12-05 05:34

    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.

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

    //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:

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

    As noted here, Swing components must honor the opaque property; in this variation, the ImageIcon completely fills the BorderLayout.CENTER of the frame's default layout.

    0 讨论(0)
  • 2020-12-05 05:36

    Calling setOpaque(false) on the upper JPanel should work.

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

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

    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).

    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);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题