在JFrame中将背景图片加载到JPanel中时出错 [英] Error loading background image into JPanel in a JFrame

查看:74
本文介绍了在JFrame中将背景图片加载到JPanel中时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JFrame,要在其中完全用JPanel占据它,并在JPanel中放入背景图像.

I have a JFrame in which I want to occupy it entirely with a JPanel and put a background image in the JPanel.

代码:

public class InicioSesion extends javax.swing.JFrame{
private Image imagenFondo;
private URL fondo;

public InicioSesion(){
    initComponents();
    try{
        fondo = this.getClass().getResource("fondo.jpg");
        imagenFondo = ImageIO.read(fondo);
    }catch(IOException ex){
        ex.printStackTrace();
        System.out.print("Image dont load"); //Dont load the message.
    }

    Container c = getContentPane();
    c.add(PanelFondo);
}

public JPanel panelFondo = new JPanel(){
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(imagenFondo, 0, 0, getWidth(), getHeight(), this);
    }
};

为什么不加载图像?我的代码有解决方案吗?

推荐答案

您的问题在这里:

initComponents();

您可能会使用此方法将所有组件添加到GUI中,很可能使用GroupLayout或其他用户不友好的布局管理器,然后在添加所有组件之后添加panelFondo JPanel.

You likely add all components to the GUI in this method, quite possibly using GroupLayout or other user-unfriendly layout manager, and then add the panelFondo JPanel after all components have been added.

如果要让GUI显示背景图像,则需要将组件添加到绘制图像的JPanel,并且如果在图像抽屉的顶部添加了任何JPanel,则它们必须是透明的(setOpaque(false) "),这样背景图片就会显示出来.

If you want a GUI to show a background image, the components need to be added to the image-drawing JPanel, and if any JPanels are added on top of the image drawer, they need to be transparent (setOpaque(false)`) so that the background image shows through.

我猜您正在使用GUI构建器来创建GUI布局并帮助您向GUI添加组件.我自己避免使用它们,更喜欢使用布局管理器(绝不为空的布局)手动创建GUI.如果绝对必须使用GUI构建器,则让该构建器为您创建一个JPanel(而不是JFrame),然后重写此JPanel的paintComponent,在其中绘制图像.否则,您最好像我一样学习Swing布局管理器并手动创建GUI.

I'm guessing that you're using a GUI builder to create your GUI layouts and to assist you in adding components to the GUI. Myself, I avoid using them and much prefer creating my GUI's by hand using layout managers (never null layouts). If you absolutely must use a GUI builder, then have the builder create a JPanel for you, not a JFrame, and then override this JPanel's paintComponent, drawing the image within it. Otherwise you may be better off learning the Swing layout managers and creating your GUI's by hand like I do.

您的窗口似乎是一个登录窗口,如果是这样,如果这是我的程序,我什至不使用JFrame而是使用 modal JDialog来显示它,因为它会这样更容易控制程序流.

Your window appears to be a sign-in window, and if so, if this were my program, I wouldn't even use a JFrame but rather a modal JDialog to display this since it would be much easier to control program flow in this way.

使用GridBagLayout的概念验证程序以及太多的幻数":

Proof of concept program using GridBagLayout and way too many "magic numbers":

import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class LoginPanel extends JPanel {
    public static final String TITLE = "INICIO DE SESIÓN";
    public static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/"
            + "commons/thumb/6/69/MarsSunset.jpg/779px-MarsSunset.jpg";
    private JTextField usuarioField = new JTextField(20);
    private JPasswordField passwordField = new JPasswordField(20);
    private BufferedImage backgroundImg = null;

    public LoginPanel(BufferedImage img) {
        this.backgroundImg = img;
        JCheckBox showPasswordChkBx = new JCheckBox("Show Password");
        showPasswordChkBx.setOpaque(false);
        showPasswordChkBx.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    passwordField.setEchoChar((char) 0);
                } else {
                    passwordField.setEchoChar('*');
                }
            }
        });

        JButton accederBtn = new JButton("Acceder");
        accederBtn.addActionListener(e -> {
            Window win = SwingUtilities.getWindowAncestor(LoginPanel.this);
            win.dispose();
        });

        setForeground(Color.BLACK);

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        int row = 0;

        gbc.gridx = 0;
        gbc.gridy = row;
        gbc.gridwidth = 2;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        int ins = 12;
        gbc.insets = new Insets(ins, ins, ins, ins);
        gbc.anchor = GridBagConstraints.CENTER;

        JLabel titleLabel = new JLabel(TITLE);
        titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 24f));
        add(titleLabel, gbc);

        row++;
        gbc.gridx = 0;
        gbc.gridy = row;
        gbc.gridwidth = 1;
        gbc.anchor = GridBagConstraints.LINE_START;
        add(new JLabel("Usuario:"), gbc);

        gbc.gridx = 1;
        add(usuarioField, gbc);

        row++;
        gbc.gridx = 0;
        gbc.gridy = row;
        gbc.insets = new Insets(ins, ins, 0, ins);
        add(new JLabel("Password:"), gbc);

        gbc.gridx = 1;
        add(passwordField, gbc);

        row++;
        gbc.gridx = 0;
        gbc.gridy = row;
        gbc.insets = new Insets(0, ins, ins, ins);
        add(new JLabel(""), gbc);

        gbc.gridx = 1;
        add(showPasswordChkBx, gbc);

        row++;
        gbc.gridx = 0;
        gbc.gridy = row;
        gbc.insets = new Insets(ins, ins, ins, ins);
        add(new JLabel(""), gbc);

        gbc.gridx = 1;
        add(accederBtn, gbc);

    }

    public String getUsuario() {
        return usuarioField.getText();
    }

    public char[] getPassword() {
        return passwordField.getPassword();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (backgroundImg != null) {
            g.drawImage(backgroundImg, 0, 0, getWidth(), getHeight(), this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension superSize = super.getPreferredSize();
        int width = superSize.width;
        int height = superSize.height;
        if (backgroundImg != null) {
            width = Math.max(width, backgroundImg.getWidth());
            height = Math.max(height, backgroundImg.getHeight());
        }
        return new Dimension(width, height);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        BufferedImage img = null;
        try {
            URL imgUrl = new URL(IMG_PATH);
            img = ImageIO.read(imgUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }

        LoginPanel mainPanel = new LoginPanel(img);
        JDialog dialog = new JDialog((JFrame) null, LoginPanel.TITLE, ModalityType.APPLICATION_MODAL);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.add(mainPanel);
        dialog.pack();
        dialog.setLocationByPlatform(true);
        dialog.setVisible(true);

        System.out.println("User Name: " + mainPanel.getUsuario());
        System.out.println("Password: " + new String(mainPanel.getPassword()));
    }
}

这篇关于在JFrame中将背景图片加载到JPanel中时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆