JPanel 图像背景与其他 JPanel 重叠

JPanel Image Background Overlapping Other JPanel

我有两个 JPanel,一个是图像,另一个是表单。我试图将带有背景图像的第一个面板放在其他(绘画)后面,但它不起作用

面板背景:

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

这是面板形式(只是为了遵循逻辑):

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

我用这个代码给他打电话:

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

我尝试了其他方法,但我得到的是背景图像覆盖所有内容,甚至连 painelCadastro() 都可见.. 有什么想法可以给我启发吗?

编辑

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

主要 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());

好的,我创建了一个辅助 class,将她的图像添加到面板,将内容设置为框架,但是当我尝试将表格变为可见时 仍然是一个或另一个

编辑 成功了,谢谢

但是... 这个'xp interface'中的复选框菜单在哪里? 另一个问题,是"label"吗?出现在gui的末尾 我想这可能是尺寸错误,因为框架是 .pack

您不能将多个组件添加到内容窗格的中心。您需要在组件之间具有父/子关系。

基本逻辑应该是:

JPanel background = new BackgroundPanel(); // this is where you paint the image
background.setLayout( new BorderLayout() );

JPanel child = new JPanel(); // this is the panel with your other components
child.setOpaque( false );

background.add( child );
frame.add( 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;
}

表面上看起来不错,但当我们仔细观察时,我注意到从方法中 returned 的面板不是作为 [=13= 应用的面板]!?

但是在您的 criarGUI 中,您使用 fundo 方法 return 将面板添加到另一个框架中......但您只是将一个空白面板添加到框架。

所以出于某种原因,您正在从 demo class 中获取内容并尝试将其添加到不同的框架中...为什么这个问题真的应该得到回答,因为那是有点担心...

另一个问题是,你一直在调用painelCadastro...

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

但是 painelCadastro 每次调用它时都会创建一个新的 JPanel,因此更改其 opaque 状态没有任何效果,因为您第二次调用它时,您会得到JPanel

的全新实例

解决办法??要么让你的方法缓存其操作的结果(又名延迟加载),并始终 return JPanel 的相同实例(最初创建的实例),要么维护对组件的引用 return编辑。此外,请确保您适当地命名您的方法,以便他们更多地了解他们所做的事情。在你的情况下 makePainelCadastrocreatePainelCadastro 可能更合适

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