Search code examples
javaswinguser-interfacejpaneloverlapping

JPanel Image Background Overlapping Other JPanel


I got two JPanels, one is an image an other a form. I'm trying to put the first panel with the background image behind other (painting) but it doesn't work

the panel background:

public JPanel fundo() {
    JPanel bg = new JPanel(new BorderLayout());
    try {
        Image backgroundImage = ImageIO.read(new File("C:/ceu.png"));
        setContentPane(new JPanel(new BorderLayout()) {
            @Override
            public void paintComponent(Graphics g) {
                g.drawImage(backgroundImage, 0, 0, null);
            }
        });
    } catch (IOException e) {
        System.out.println(e);
    }
    return bg;
}

and this is the panel form (only to follow the logic):

public JPanel painelCadastro() {
    JPanel telaAtual = new JPanel();
    JTextField nome, telefone, aniversario, email;
    String definicao;
    JLabel lugarnome, lugartelefone, lugaraniversario, lugaremail;
    JTextArea endereço;

    telaAtual.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    //c.anchor = GridBagConstraints.WEST;
    //c.ipadx = 2;
    //c.ipady = 3;
    //c.gridheight = GridBagConstraints.REMAINDER;  
    //c.gridwidth = GridBagConstraints.REMAINDER;  

    lugarnome = new JLabel("Nome");
    c.weightx = 1; // percentual de tamanho em relação aos demais
    c.gridwidth = 1; //tamanho do compontente em celulas HORIZONTAL
    c.gridheight = 1; //tamanho do compontente em celulas VERTICAL
    c.gridx = 0; //localização da celula na coluna
    c.gridy = 0; //localização da celula na linha
    //c.fill = GridBagConstraints.HORIZONTAL;
    c.insets = new Insets(10, 10, 0, 0);
    telaAtual.add(lugarnome, c);

    nome = new JTextField("Digite seu nome aqui");
    definicao = "nome";
    c.weightx = 1; // percentual de tamanho em relação aos demais
    c.gridwidth = 7; //tamanho do compontente em celulas HORIZONTAL
    c.gridx = 1; //localização da celula na linha
    c.gridy = 0; //localização da celula na coluna
    //c.fill = GridBagConstraints.HORIZONTAL;
    limpaCaixaTexto(nome, definicao);
    telaAtual.add(nome, c);

    lugartelefone = new JLabel("Telefone");
    c.weightx = 1; // percentual de tamanho em relação aos demais
    c.gridx = 0; //localização da celula na linha
    c.gridy = 1; //localização da celula na coluna
    c.fill = GridBagConstraints.NONE;
    telaAtual.add(lugartelefone, c);

    telefone = new JTextField("Digite seu telefone aqui");
    definicao = "telefone";
    c.weightx = 2; // percentual de tamanho em relação aos demais
    c.gridx = 1; //localização da celula na linha
    c.gridy = 1; //localização da celula na coluna
    c.fill = GridBagConstraints.HORIZONTAL;
    limpaCaixaTexto(telefone, definicao);
    telaAtual.add(telefone, c);

    lugaremail = new JLabel("Email");
    c.weightx = 1; // percentual de tamanho em relação aos demais
    c.gridx = 0; //localização da celula na linha
    c.gridy = 2; //localização da celula na coluna
    c.fill = GridBagConstraints.NONE;
    telaAtual.add(lugaremail, c);

    email = new JTextField("Digite seu e-mail aqui");
    definicao = "e-mail";
    c.weightx = 2; // percentual de tamanho em relação aos demais
    c.gridx = 1; //localização da celula na linha
    c.gridy = 2; //localização da celula na coluna
    c.fill = GridBagConstraints.HORIZONTAL;
    limpaCaixaTexto(email, definicao);
    telaAtual.add(email, c);

    //--------- INICIO CAMPO DATA -------------
    lugaraniversario = new JLabel("Data de Nascimento");
    c.weightx = 1; // percentual de tamanho em relação aos demais
    c.gridx = 0; //localização da celula na linha
    c.gridy = 3; //localização da celula na coluna
    c.fill = GridBagConstraints.NONE;
    telaAtual.add(lugaraniversario, c);

    //JFormattedTextField dataAniversario = new JFormattedTextField(DateFormat.getDateInstance(DateFormat.MEDIUM));
    //GregorianCalendar data = new GregorianCalendar();
    //dataAniversario.setText(data.get(Calendar.DAY_OF_MONTH) + "/" + (data.get(Calendar.MONTH) + 1) + "/" + (data.get(Calendar.YEAR)));
    DateFormat df = new SimpleDateFormat("dd/mm/yyyy");
    JFormattedTextField dataAniversario = new JFormattedTextField(df);
    try {
        MaskFormatter dateMask = new MaskFormatter("##/##/####");
        dateMask.install(dataAniversario);

    } catch (ParseException ex) {
        Logger.getLogger(TelaPrincipalLocadora.class
                .getName()).log(Level.SEVERE, null, ex);
    }
    definicao = "aniversario";
    c.weightx = 2; // percentual de tamanho em relação aos demais
    c.gridx = 1; //localização da celula na linha
    c.gridy = 3; //localização da celula na coluna
    c.fill = GridBagConstraints.HORIZONTAL;
    limpaCaixaTexto(dataAniversario, definicao);
    telaAtual.add(dataAniversario, c);

    //--------- FIM CAMPO DATA -------------
    return telaAtual;
}

I'm calling him with this code:

private static void criarGUI() throws IOException {
    //Create and set up the window.
    JFrame frame = new JFrame("Vapstor Locadoras V1.0");
    frame.setSize(590, 456);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setLayout(new BorderLayout());

    TelaPrincipalLocadora demo = new TelaPrincipalLocadora();
    frame.setJMenuBar(demo.BarradeMenu());
    demo.painelCadastro().setVisible(false);

    frame.add(demo.painelCadastro()); //~HERE HE ADD

    frame.add(demo.fundo());
    System.out.println(demo.painelCadastro().isVisible()); // returns true

    demo.fundo().setOpaque(false); //HERE 
    frame.add(demo.fundo()); //AND HERE i guess is the problem

    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setVisible(true);
}

I try other ways, and what i just get is the background image overlapping everything, even the painelCadastro() being visible.. Any ideas to give me a light?

EDIT

static class Background extends JComponent {

    Image backgroundImage;

    public Background() throws IOException {
        this.backgroundImage = ImageIO.read(new File("C:/ceu.png"));
    }

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(backgroundImage, 0, 0, this);
        System.out.println("pintou o 7");
    }
}

on the main class:

    JPanel tela = new JPanel(new BorderLayout());
    tela.add(new Background());
    tela.setOpaque(false);
    frame.setContentPane(tela);
    //frame.setAlwaysOnTop(true);
    demo.painelCadastro().setOpaque(false);
    frame.add(demo.painelCadastro());

alright, i creat a secondary class, add the imagem from her to a panel, set the content to frame, but when i try to turn the form visible still one or other

EDIT it works, gracias

but... Where is the checkbox menuitens in this 'xp interface'? Another question, is that a "label"? appears at the end of gui I guess it just can be the Dimension wrong, because the frame is .pack


Solution

  • So, I'm trying to make heads and tails of your code...

    First we have...

    public JPanel fundo() {
        JPanel bg = new JPanel(new BorderLayout());
        try {
            Image backgroundImage = ImageIO.read(new File("C:/ceu.png"));
            setContentPane(new JPanel(new BorderLayout()) {
                @Override
                public void paintComponent(Graphics g) {
                    g.drawImage(backgroundImage, 0, 0, null);
                }
            });
        } catch (IOException e) {
            System.out.println(e);
        }
        return bg;
    }
    

    which on surface looks okay, but when we take a closer look at I notice that the panel which is been returned from the method IS NOT the panel which is been applied as the contentPane!?

    But in your criarGUI you take the panel returned by the fundo method and add it to another frame ... but you're just adding a blank panel to the frame.

    So for some reason you're taking content from the demo class and trying to add it to a different frame...why is a question that should really be answered, because that's kind of worrying...

    Another problem is, you keep calling painelCadastro...

    demo.painelCadastro().setOpaque(false);
    frame.add(demo.painelCadastro());
    

    but painelCadastro creates a new JPanel each time you call it, so changing its opaque state has no effect, as the second time you call it, you're getting a brand new instance of JPanel

    The solution?? Either have your methods cache the result (AKA lazy loading) of their operations and always return the same instance of JPanel (which the initially created) or maintain a reference to the component which is returned. Also, make sure you name your methods appropriately so they give more of an idea of what they do. In your case makePainelCadastro or createPainelCadastro might be more appropriate

    Background

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import javax.imageio.ImageIO;
    import javax.swing.JFormattedTextField;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.text.MaskFormatter;
    
    public class Testing {
    
        public static void main(String[] args) {
            new Testing();
        }
    
        public Testing() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        try {
                            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                            ex.printStackTrace();
                        }
    
                        JFrame frame = new JFrame("Testing");
                        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        frame.setContentPane(new Background());
                        JPanel painelCadastro = painelCadastro();
                        painelCadastro.setOpaque(false);
                        frame.add(painelCadastro);
                        frame.pack();
                        frame.setLocationRelativeTo(null);
                        frame.setVisible(true);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            });
        }
    
        public JPanel painelCadastro() {
            JPanel telaAtual = new JPanel();
            JTextField nome, telefone, aniversario, email;
            String definicao;
            JLabel lugarnome, lugartelefone, lugaraniversario, lugaremail;
            JTextArea endereço;
    
            telaAtual.setLayout(new GridBagLayout());
            GridBagConstraints c = new GridBagConstraints();
            //c.anchor = GridBagConstraints.WEST;
            //c.ipadx = 2;
            //c.ipady = 3;
            //c.gridheight = GridBagConstraints.REMAINDER;  
            //c.gridwidth = GridBagConstraints.REMAINDER;  
    
            lugarnome = new JLabel("Nome");
            c.weightx = 1; // percentual de tamanho em relação aos demais
            c.gridwidth = 1; //tamanho do compontente em celulas HORIZONTAL
            c.gridheight = 1; //tamanho do compontente em celulas VERTICAL
            c.gridx = 0; //localização da celula na coluna
            c.gridy = 0; //localização da celula na linha
            //c.fill = GridBagConstraints.HORIZONTAL;
            c.insets = new Insets(10, 10, 0, 0);
            telaAtual.add(lugarnome, c);
    
            nome = new JTextField("Digite seu nome aqui");
            definicao = "nome";
            c.weightx = 1; // percentual de tamanho em relação aos demais
            c.gridwidth = 7; //tamanho do compontente em celulas HORIZONTAL
            c.gridx = 1; //localização da celula na linha
            c.gridy = 0; //localização da celula na coluna
            //c.fill = GridBagConstraints.HORIZONTAL;
    //      limpaCaixaTexto(nome, definicao);
            telaAtual.add(nome, c);
    
            lugartelefone = new JLabel("Telefone");
            c.weightx = 1; // percentual de tamanho em relação aos demais
            c.gridx = 0; //localização da celula na linha
            c.gridy = 1; //localização da celula na coluna
            c.fill = GridBagConstraints.NONE;
            telaAtual.add(lugartelefone, c);
    
            telefone = new JTextField("Digite seu telefone aqui");
            definicao = "telefone";
            c.weightx = 2; // percentual de tamanho em relação aos demais
            c.gridx = 1; //localização da celula na linha
            c.gridy = 1; //localização da celula na coluna
            c.fill = GridBagConstraints.HORIZONTAL;
    //      limpaCaixaTexto(telefone, definicao);
            telaAtual.add(telefone, c);
    
            lugaremail = new JLabel("Email");
            c.weightx = 1; // percentual de tamanho em relação aos demais
            c.gridx = 0; //localização da celula na linha
            c.gridy = 2; //localização da celula na coluna
            c.fill = GridBagConstraints.NONE;
            telaAtual.add(lugaremail, c);
    
            email = new JTextField("Digite seu e-mail aqui");
            definicao = "e-mail";
            c.weightx = 2; // percentual de tamanho em relação aos demais
            c.gridx = 1; //localização da celula na linha
            c.gridy = 2; //localização da celula na coluna
            c.fill = GridBagConstraints.HORIZONTAL;
    //      limpaCaixaTexto(email, definicao);
            telaAtual.add(email, c);
    
            //--------- INICIO CAMPO DATA -------------
            lugaraniversario = new JLabel("Data de Nascimento");
            c.weightx = 1; // percentual de tamanho em relação aos demais
            c.gridx = 0; //localização da celula na linha
            c.gridy = 3; //localização da celula na coluna
            c.fill = GridBagConstraints.NONE;
            telaAtual.add(lugaraniversario, c);
    
            //JFormattedTextField dataAniversario = new JFormattedTextField(DateFormat.getDateInstance(DateFormat.MEDIUM));
            //GregorianCalendar data = new GregorianCalendar();
            //dataAniversario.setText(data.get(Calendar.DAY_OF_MONTH) + "/" + (data.get(Calendar.MONTH) + 1) + "/" + (data.get(Calendar.YEAR)));
            DateFormat df = new SimpleDateFormat("dd/mm/yyyy");
            JFormattedTextField dataAniversario = new JFormattedTextField(df);
            try {
                MaskFormatter dateMask = new MaskFormatter("##/##/####");
                dateMask.install(dataAniversario);
    
            } catch (ParseException ex) {
                ex.printStackTrace();
            }
            definicao = "aniversario";
            c.weightx = 2; // percentual de tamanho em relação aos demais
            c.gridx = 1; //localização da celula na linha
            c.gridy = 3; //localização da celula na coluna
            c.fill = GridBagConstraints.HORIZONTAL;
    //      limpaCaixaTexto(dataAniversario, definicao);
            telaAtual.add(dataAniversario, c);
    
            //--------- FIM CAMPO DATA -------------
            return telaAtual;
        }
    
        public class Background extends JPanel {
    
            private BufferedImage backgroundImage;
    
            public Background() throws IOException {
                this.backgroundImage = ImageIO.read(new File("..."));
                setLayout(new BorderLayout());
            }
    
            @Override
            public Dimension getPreferredSize() {
                return backgroundImage == null ? new Dimension(200, 200) : new Dimension(backgroundImage.getWidth(), backgroundImage.getHeight());
            }
    
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(backgroundImage, 0, 0, this);
            }
        }
    }