如何在项目运行时更改JFrame背景图像

时间:2016-06-12 00:00:02

标签: java swing background jpanel

我用

设置背景
static JLabel board = new JLabel(new ImageIcon("img/rsz_board.png"));
frame.setContentPane(board);

我尝试用按钮改变背景:

static JLabel board2 = new JLabel(new ImageIcon("img/board.png"));
JButton button2 = new JButton("Test");
button2.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
        frame.setContentPane(board2);
    }
});

当我点击按钮时,什么都不会发生。如果我单击按钮然后通过用光标拖动来调整窗口大小,背景将会改变,但我的所有按钮都会消失。我做错了什么?

3 个答案:

答案 0 :(得分:1)

我认为您应该在更改背景后使用revalidate()repaint()

试试这个:

static JLabel board2 = new JLabel(new ImageIcon("img/board.png"));
JButton button2 = new JButton("Test");
button2.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
        frame.setContentPane(board2);
        frame.revalidate();
        frame.repaint();
    }
});

答案 1 :(得分:1)

也许更好的方法来做你想要的:创建一个JPAnel,在其paintComponent方法中在后台绘制图像,它有自己的布局管理器,这有助于你以任何你认为合适的方式向JPanel添加组件。您将为此类提供一个Image字段,然后在paintComponent方法中绘制该字段引用的任何图像。或者,如果要交换图像集合,请为其指定ArrayList<Image>字段(下面称为图像),然后将索引引用的当前图像绘制到该列表中(在下面的代码中称为imageIndex)。

对您的代码的评论:

  • 您正在为某些Swing组件使用静态变量,这表明您应该重新考虑您的设计。只声明静态的静态,而Swing GUI组件几乎从不在该类别中。
  • 当您使用JLabel时,标签始终会根据图像及其保留的文本(如果有)进行调整,这对某些应用程序来说是正常的,但对其他应用程序则很危险。 JPanel会根据布局将其首选大小设置为它所拥有的组件的大小。如果您像我一样明确地更改其getPreferredSize()方法,那么所有这些都会发生变化。

例如,编译并运行下面的完整程序代码:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class ChangeBackground extends JPanel {
    public static final String ROOT_PATH = "https://upload.wikimedia.org/wikipedia/commons/thumb/";
    public static final String[] IMG_PATHS = {
        "0/01/Sundomecloseup.JPG/640px-Sundomecloseup.JPG",
        "3/31/Hanalei,_Kauai_HI.JPG/640px-Hanalei,_Kauai_HI.JPG",
        "a/a3/Castle_of_Vajdahunyad.jpg/640px-Castle_of_Vajdahunyad.jpg",
        "d/d6/HeratFridayMosque.jpg/640px-HeratFridayMosque.jpg",
        "1/16/Hebridean_ram.jpg/640px-Hebridean_ram.jpg",
        "1/11/Ouagadougou_Maison_du_peuple.jpg/640px-Ouagadougou_Maison_du_peuple.jpg",
        "9/96/Menger-Schwamm-einfarbig.jpg/640px-Menger-Schwamm-einfarbig.jpg",
        "4/4f/Olympias.1.JPG/640px-Olympias.1.JPG",
        "1/18/Uscapitolindaylight.jpg/640px-Uscapitolindaylight.jpg",
        "9/9a/Below_Golden_Gate_Bridge.jpeg/640px-Below_Golden_Gate_Bridge.jpeg",
        "2/29/Eiffel_Tower_(2962488972).jpg/640px-Eiffel_Tower_(2962488972).jpg",
        "8/8f/Notre-Dame_Cathedral_Basilica.jpg/640px-Notre-Dame_Cathedral_Basilica.jpg"
        };
    private static final int PREF_W = 640;
    private static final int PREF_H = 480;
    private List<Image> images = new ArrayList<>();
    private int imageIndex = 0;

    public ChangeBackground(List<Image> images) {
        this.images = images;

        add(new JButton(new NextImageAction("Next Image")));
    }

    public void nextImage() {
        imageIndex++;
        imageIndex %= images.size();
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private class NextImageAction extends AbstractAction {
        public NextImageAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent arg0) {
            nextImage();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(images.get(imageIndex), 0, 0, this);
    }

    private static void createAndShowGui(final List<Image> images) {
        ChangeBackground mainPanel = new ChangeBackground(images);

        JFrame frame = new JFrame("ChangeBackground");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        final List<Image> imgs = new ArrayList<>();
        for (String imagePath : IMG_PATHS) {
            imagePath = ROOT_PATH + imagePath;
            try {
                URL imgUrl = new URL(imagePath);
                imgs.add(ImageIO.read(imgUrl));
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        SwingUtilities.invokeLater(() -> createAndShowGui(imgs));
    }
}

答案 2 :(得分:1)

  

如果我点击按钮然后用光标拖动它来调整窗口大小,背景会改变,但我的所有按钮都会消失

这是因为所有按钮都已添加到“board”组件而不是“board2”组件。

  

我尝试使用按钮更改背景:

请勿更改用作内容窗格的标签。而是更改标签的图标:

//frame.setContentPane(board2);
board.setIcon( new ImageIcon("img/board.png") );