奇怪的背景JSwing图像加载

J4102

在此处输入图片说明 在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

我似乎无法弄清楚如何在显示所有面板的情况下添加背景。

我试图将JFrame内容窗格设置为带有imageicon的标签,并且该框架的确显示了,只是没有显示上述图像。

这是我使用的代码。

frame.setContentPane(new JLabel(new ImageIcon("res/Wallpaper.png")));

我使用过的第二种方法是将图像添加(而不是设置)到框架的内容窗格中。如上第二张图片所示,此操作无效,它仅显示面板,但没有背景。代码在底部。

frame.getContentPane().add(new JLabel(new ImageIcon("res/Wallpaper.png")));

我尝试的第三次尝试是创建JComponent的子类并重写paintComponents方法,然后将其对象设置为contentpane。这不起作用,而是将我的屏幕变为空白。

Here is the code I've used and the class code is in the 1st answer of this link Setting background images in JFrame. The result is the 3rd image of this post.

        File img = new File("res/Wallpaper.png");

    BufferedImage myImage;
    try {
        myImage = ImageIO.read(img);
        frame.setContentPane(new ImagePanel(myImage));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

The 4th attempt I've tried is adding the picture into the main panel that fills up the screen. This does not work at all and instead breaks the image in half so half of the screen has the image half doesn't.

Here is the code I've used for my 4th attempt. The result is the 4th last image on the top.

        BufferedImage myPicture;
    try {
        myPicture = ImageIO.read(new File("res/Wallpaper.png"));
        JLabel picLabel = new JLabel(new ImageIcon(myPicture));
        pMain.add(picLabel);
    } catch (IOException e) {
        e.printStackTrace();
    }

I'm not sure why the JPanels aren't showing up.

I know that in the 1st example when you set the frame as a JLabel it gives it a null layout but that was the only way I could find to DISPLAY the image.

I would like to somehow add the panels ontop of the frame with that background but after reading numerous threads I could not find out how.

If anyone does find out, please post the code and explain if you can. I also have the class get the system class theme that sets it into the theme of what the computer is using. Ex. I am using a windows operating system so it shows it kind of like my operating system.

This thread is not a duplicate. In other threads they only have a frame but in my thread I have several panels that aren't showing for some particular reason.

EDIT: I don't know what's up, I tried to use this thread Setting background images in JFrame but I had no luck.

The 1st method it gave me I tried and then instead of showing anything it showed nothing at all, no picture no components nothing at all. In case if you need more information I have: 4 JPanels on the bottom of the screen, I also have a border surrounding my window but doesn't show up in the 1st window. I also have borders surrounding my panels too.

So the 1st method I've tried setting it on the content pane, image loads but all of the components are gone.

2nd method I've tried adding it into the content pane but yet again with no luck and I get a panel with no background.

3rd method I've tried is creating a separate class and overriding the paintComponent method and adding an image to the constructor of it then placing this object of the class into the setcontentPane() parameter of the frame. Does not work at all, all I get is a blank frame.

Code I am using for my frame:

public class LoginScreen {

JCheckBox remember_User;
JButton login, create_Account, forums, faqs;
Border whiteLine;
JTextField userField;
JFormattedTextField passField;

private void createView() {
    // Created essential details for the frame
    JFrame frame = new JFrame();
    frame.setTitle("Name of the game");
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // Defining panels and a constraint on the bottomPanel.
    // More info - Total amt of panels: 5
    // pLogin and pInfo are in the bottomCompPanel and bottomCompPanel is in
    // bottomPanel
    // bottom panel is in pMain
    // Giving panels some attributes like backgrounds and borders
    JPanel pMain = new JPanel(new BorderLayout());
    pMain.setBorder(BorderFactory.createMatteBorder(3, 3, 6, 3,
            Color.DARK_GRAY));
    frame.getContentPane().add(pMain);

    whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);

    JPanel pLogin = new JPanel(new GridBagLayout());
    pLogin.setBackground(Color.cyan);
    pLogin.setPreferredSize(new Dimension(400, 250));
    pLogin.setBorder(whiteLine);

    JPanel pInfo = new JPanel(new GridBagLayout());
    pInfo.setBackground(Color.green);
    pInfo.setPreferredSize(new Dimension(200, 100));
    pInfo.setBorder(whiteLine);

    JPanel bottomCompPanel = new JPanel(new GridBagLayout());
    GridBagConstraints bGBC = new GridBagConstraints();
    bGBC.gridx = 0;
    bGBC.gridy = 0;
    bGBC.insets = new Insets(0, 20, 0, 0);
    bGBC.anchor = GridBagConstraints.PAGE_END;

    bottomCompPanel.add(pLogin, bGBC);
    bGBC.gridx++;
    bottomCompPanel.add(pInfo, bGBC);

    JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

    bottomPanel.add(bottomCompPanel);
    pMain.add(bottomPanel, BorderLayout.SOUTH);
    frame.setVisible(true);
}

public static void main(String[] args) {
    LoginScreen login = new LoginScreen();
    login.createView();
}

}

POST UPDATE 2: Here is the code that I've used using @peeskillet's 1st method. It works sort of but it gives me the same results as the 3rd photo, a cut off picture. P.S I add the panels down at the bottom to my JLabel at the end.

private void createView() {

    //Created essential details for the frame
    JFrame frame = new JFrame();
    frame.setTitle("Name of the game");
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);

    JLabel background = new JLabel(new ImageIcon("res/Wallpaper.png"));
    background.setLayout(new BorderLayout());
    frame.setContentPane(background);


    //Defining panels and a constraint on the bottomPanel. 
    //More info - Total amt of panels: 5
    //pLogin and pInfo are in the bottomCompPanel and bottomCompPanel is in bottomPanel
    //bottom panel is in pMain
    //Giving panels some attributes like backgrounds and borders

    whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);

    JPanel pLogin = new JPanel(new GridBagLayout());
    pLogin.setBackground(Color.cyan);
    pLogin.setPreferredSize(new Dimension(400,250));
    pLogin.setBorder(whiteLine);

    JPanel pInfo = new JPanel(new GridBagLayout());
    pInfo.setBackground(Color.green);
    pInfo.setPreferredSize(new Dimension(200,100));
    pInfo.setBorder(whiteLine);

    JPanel bottomCompPanel = new JPanel(new GridBagLayout());

    GridBagConstraints bGBC = new GridBagConstraints();
    bGBC.gridx = 0;
    bGBC.gridy = 0;
    bGBC.insets = new Insets(0,20,0,0);
    bGBC.anchor = GridBagConstraints.PAGE_END;

    bottomCompPanel.add(pLogin, bGBC);
    bGBC.gridx++;
    bottomCompPanel.add(pInfo, bGBC);

    JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

    bottomPanel.add(bottomCompPanel);
    background.add(bottomPanel, BorderLayout.SOUTH);
Paul Samsotha

"I tried to set the JFrame content pane as a label with an imageicon"

You need to set the layout on the JLabel. It will be null be default.

import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;

public class BackgroundImage {

    private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";

    private void init() throws Exception {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel background = new JLabel(new ImageIcon(new URL(IMG)));
        background.setLayout(new GridBagLayout());
        background.add(loginPanel());
        f.setContentPane(background);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JPanel loginPanel() {
        Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
        JPanel pLogin = new JPanel(new GridBagLayout());
        pLogin.setBackground(Color.cyan);
        pLogin.setPreferredSize(new Dimension(400, 250));
        pLogin.setBorder(whiteLine);
        return pLogin;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                new BackgroundImage().init();
            } catch (Exception ex) {}
        });
    }
}

在此处输入图片说明

"I've tried is to create a subclass of JComponent and Override the paintComponents method then setan object of it as the contentpane"

Should be paintComponent (no "s"), but just like with JLabel, you need to set the layout. JComponent layout is null be default. You also need to give it a preferred size when painting.

import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;

public class BackgroundImage {

    private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";

    private void init() throws Exception {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JComponent background = new BackgroundComponent(new ImageIcon(new URL(IMG)));
        background.setLayout(new GridBagLayout());
        background.add(loginPanel());
        f.setContentPane(background);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JPanel loginPanel() {
        Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
        JPanel pLogin = new JPanel(new GridBagLayout());
        pLogin.setBackground(Color.cyan);
        pLogin.setPreferredSize(new Dimension(400, 250));
        pLogin.setBorder(whiteLine);
        return pLogin;
    }

    class BackgroundComponent extends JComponent {
        public ImageIcon background;
        public BackgroundComponent(ImageIcon background) {
            this.background = background;
        }
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(background.getIconWidth(), background.getIconHeight());
        }
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(background.getImage(),
                        0, 0,
                        background.getIconWidth(), 
                        background.getIconHeight(), this);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                new BackgroundImage().init();
            } catch (Exception ex) {}
        });
    }
}

在此处输入图片说明

Using (extending) JPanel instead of JComponent would be similar except JPanel does have a default layout which is FlowLayout.


UPDATE

To get your desired layout, you need to play around with the different layout managers. The combination I used is

Outer (main panel)     -- BorderLayout
Bottom (bottom panel)  -- BoxLayout inside (south) of outer layout

For the BorderLayout, you need to make sure the panel opaque property is set to false, as BorderLayout will stretch the panel and cover the background.

对于BoxLayout,您需要确保设置最大尺寸和首选尺寸

import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;

public class BackgroundImage {

    private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";
    private final Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);


    private void init() throws Exception {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JComponent background = new BackgroundComponent(new ImageIcon(new URL(IMG)));
        background.setLayout(new BorderLayout());
        background.add(bottomPanel(), BorderLayout.SOUTH);
        f.setContentPane(background);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JPanel bottomPanel() {
        JPanel bottomPanel = new JPanel();
        bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        BoxLayout layout = new BoxLayout(bottomPanel, BoxLayout.X_AXIS);
        bottomPanel.setLayout(layout);
        bottomPanel.setOpaque(false);
        bottomPanel.add(Box.createHorizontalGlue());
        bottomPanel.add(loginPanel());
        bottomPanel.add(Box.createRigidArea(new Dimension(10, 0)));
        bottomPanel.add(infoPanel());
        return bottomPanel;
    }

    private JPanel infoPanel() {
        JPanel pInfo = new JPanel(new GridBagLayout());
        pInfo.setAlignmentY(Component.BOTTOM_ALIGNMENT);
        pInfo.setBackground(Color.green);
        pInfo.setMaximumSize(new Dimension(200, 100));
        pInfo.setPreferredSize(new Dimension(200, 100));
        pInfo.setBorder(whiteLine);
        return pInfo;
    }

    private JPanel loginPanel() {
        JPanel pLogin = new JPanel(new GridBagLayout());
        pLogin.setAlignmentY(Component.BOTTOM_ALIGNMENT);
        pLogin.setBackground(Color.cyan);
        pLogin.setPreferredSize(new Dimension(400, 250));
        pLogin.setMaximumSize(new Dimension(400, 250));
        pLogin.setBorder(whiteLine);
        return pLogin;
    }

    class BackgroundComponent extends JComponent {

        public ImageIcon background;

        public BackgroundComponent(ImageIcon background) {
            this.background = background;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(background.getIconWidth(), background.getIconHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(background.getImage(),
                    0, 0,
                    background.getIconWidth(),
                    background.getIconHeight(), this);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                new BackgroundImage().init();
            } catch (Exception ex) {
            }
        });
    }
}

在此处输入图片说明

有关使用不同布局管理器的更多信息,请参见

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章