Search code examples
javaswinggraphicstransparencyjlabel

Make JLabel background transparent in a frame with background


I have a JLabel on my JFrame and a JFrame with a picture background. The problem is although my JLabel is opaque but it still has a grey background which is annoying.
Here is my code:

import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class MainFrame extends JFrame {

    private JTextField username;
    private JPasswordField password;
    private JLabel passwordLbl;
    private JLabel usernameLbl;
    private GridBagConstraints gc;

    public MainFrame() {

        username = new JTextField(10);
        password = new JPasswordField(10);
        passwordLbl = new JLabel("Password: ");
        usernameLbl = new JLabel("Username: ");

        usernameLbl.setOpaque(true);
        passwordLbl.setOpaque(true);

        setLayout(new GridBagLayout());

        gc = new GridBagConstraints();
        gc.weightx = 1;
        gc.weighty = 1;

        gc.gridx = 1;
        gc.gridy = 0;
        add(username, gc);

        gc.gridx = 1;
        gc.gridy = 1;
        add(password, gc);

        gc.gridx = 0;
        gc.gridy = 0;
        add(usernameLbl, gc);

        gc.gridx = 0;
        gc.gridy = 1;
        add(passwordLbl, gc);

        setSize(400, 600);
        setLocation(400, 50);

        setUndecorated(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);

    }

    @Override
    public void paint(Graphics arg0) {
        Image img = getToolkit().getImage("pics/blue_and_red.jpg");

        arg0.drawImage(img, 0, 0, getWidth(), getHeight(), this);

        username.repaint();
        password.repaint();
        usernameLbl.setOpaque(true);
        usernameLbl.repaint();
        passwordLbl.repaint();

    }
}

Thanks in advance.


Solution

  • Your paint method is completely farked is the reason for your problem. Don't draw your labels in paint, but do call super.paint(g) in there.

    Better still, don't draw in a JFrame's paint method but rather in a JPanel's paintComponent method and call the super's method there.

    i.e.,

    public class MainPanel extends JPanel {
    
        private JTextField username;
        private JPasswordField password;
        private JLabel passwordLbl;
        private JLabel usernameLbl;
        private GridBagConstraints gc;
        private Image img;
    
        public MainPanel() {
            img = getToolkit().getImage("pics/blue_and_red.jpg");
    
            username = new JTextField(10);
            password = new JPasswordField(10);
            passwordLbl = new JLabel("Password: ");
            usernameLbl = new JLabel("Username: ");
    
            // usernameLbl.setOpaque(true);
            // passwordLbl.setOpaque(true);
    
            setLayout(new GridBagLayout());
    
            gc = new GridBagConstraints();
            gc.weightx = 1;
            gc.weighty = 1;
    
            gc.gridx = 1;
            gc.gridy = 0;
            add(username, gc);
    
            gc.gridx = 1;
            gc.gridy = 1;
            add(password, gc);
    
            gc.gridx = 0;
            gc.gridy = 0;
            add(usernameLbl, gc);
    
            gc.gridx = 0;
            gc.gridy = 1;
            add(passwordLbl, gc);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {
                g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
            }
    
            // username.repaint();
            // password.repaint();
            // usernameLbl.setOpaque(true);
            // usernameLbl.repaint();
            // passwordLbl.repaint();
        }
    
        private static void createAndShowGui() {
          // create JFrame
          JFrame frame = new JFrame("BUI");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
          // add our MainPanel to the JFrame
          frame.getContentPane().add(new MainPanel());
          frame.pack(); // pack it
          frame.setLocationByPlatform(true);
          frame.setVisible(true); // show it
       }
    
       public static void main(String[] args) {
          // this is for starting our Swing app on the event thread
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    
    }
    

    Most important, read the Painting with Swing standard Swing tutorial, as it's all well explained there.