背景JSwing图像加载奇怪

时间:2015-10-12 18:40:51

标签: java swing jframe jpanel jlabel

enter image description here enter image description here

enter image description here

enter image description here

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

我尝试将JFrame内容窗格设置为带有imageicon的标签,框架确实显示,它不会像上面那样显示图像。

这是我使用的代码。

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

我使用过的第二次尝试是将图像添加(未设置)到帧的内容窗格中。这不起作用,如上面的第二张图所示,它只显示面板但没有背景。代码位于底部。

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

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

以下是我使用的代码,类代码位于此链接Setting background images in JFrame的第一个答案中。结果是这篇文章的第3张图片。

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

我尝试过的第四次尝试是将图片添加到填满屏幕的主面板中。这根本不起作用,而是将图像分成两半,因此屏幕的一半有一半的图像没有。

以下是我第四次尝试使用的代码。结果是顶部的第4个最后一个图像。

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

我不确定为什么JPanels不会出现。

我知道在第一个例子中,当你将框架设置为JLabel时,它给它一个空布局,但这是我找到显示图像的唯一方法。

我想以某种方式添加具有该背景的框架顶部的面板但是在阅读了许多线程后我无法找到方法。

如果有人发现,请发布代码并说明是否可以。我也有类获取系统类主题,将其设置为计算机使用的主题。防爆。我正在使用Windows操作系统,因此它显示它有点像我的操作系统。

此主题不重复。在其他线程中,他们只有一个框架,但在我的线程中,我有几个面板,由于某些特殊原因没有显示。

编辑:我不知道发生了什么,我试图使用这个帖子Setting background images in JFrame,但我没有运气。

它给我的第一种方法我试过,然后没有显示任何东西它没有显示任何东西,没有图片没有组件什么都没有。如果您需要更多信息,我需要:屏幕底部有4个JPanels,我的窗口周围还有一个边框,但在第一个窗口中没有显示。我的面板周围也有边框。

所以第一种方法我尝试在内容窗格上设置它,图像加载但所有组件都消失了。

第二种方法我尝试将其添加到内容窗格中但又没有运气,我得到一个没有背景的面板。

我试过的第三种方法是创建一个单独的类并重写paintComponent方法并将一个图像添加到它的构造函数中,然后将该类的该对象放入框架的setcontentPane()参数中。根本不起作用,我得到的只是一个空白框架。

我用于我的框架的代码:

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:这是我使用@peeskillet的第一种方法使用的代码。它有点像但它给我的结果与第3张照片相同,即截止图片。 P.S我在底部向下添加面板到我的JLabel。

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

2 个答案:

答案 0 :(得分:2)

  

“我尝试将JFrame内容窗格设置为带有imageicon的标签”

您需要在JLabel上设置布局。默认为null。

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

enter image description here

  

“我试过创建一个JComponent的子类并覆盖paintComponents方法然后将它的对象设置为contentpane”

应该是paintComponent(不是“s”),但与JLabel一样,您需要设置布局。 JComponent布局为null是默认值。绘画时还需要给它一个首选尺寸。

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

enter image description here

使用(扩展)JPanel代替JComponent类似,除了JPanel 具有FlowLayout的默认布局。

更新

要获得所需的布局,您需要使用不同的布局管理器。我使用的组合是

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

对于BorderLayout,您需要确保面板opaque属性设置为false,因为BorderLayout将拉伸面板并覆盖背景。

对于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) {
            }
        });
    }
}

enter image description here

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

答案 1 :(得分:1)

您可以尝试使用JLayeredPane和setOpaque(boolean)方法。
代码:

public class BackgroundImageTest{
    private JFrame frame;

    public BackgroundImageTest() {
        frame = new JFrame("Background Image Frame");

        // set frame properties

        JPanel panel = new JPanel(new FlowLayout());
        panel.setOpaque(false);
        JButton btn = new JButton("Change Background");
        panel.add(btn);

        btn.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae) {
                setBackgroundImage(getImage(new File("Wallpaper2.png")));
            }
        });

        JPanel main = (JPanel) frame.getContentPane();
        main.setLayout(new FlowLayout());
        main.add(panel);
        main.setOpaque(false);

        setBackgroundImage(getImage(new File("Wallpaper.png")));

        frame.setVisible(true);
    }

    private Image getImage(File imageFile) {
        BufferedImage image = null;

        try {
            image = ImageIO.read(imageFile);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return image;
    }

    private void setBackgroundImage(Image img) {
        if(img == null) return;

        ImageIcon ii = new ImageIcon(img);
        JLabel lblBG = new JLabel(ii);
        lblBG.setName("BackgroundImageLabel");

        JLayeredPane layeredPane = frame.getLayeredPane();

        Component[] comps = layeredPane.getComponentsInLayer(new Integer(Integer.MIN_VALUE));
        for (int i = 0; i < comps.length; i++) {
            System.out.println(comps[i].getName());

            if (comps[i] instanceof JLabel && comps[i].getName().equals("BackgroundImageLabel")){
                layeredPane.remove(comps[i]);
                break;
            }
        }

        layeredPane.add(lblBG, new Integer(Integer.MIN_VALUE));
        lblBG.setBounds(0,0,ii.getIconWidth(), ii.getIconHeight());
    }
}