Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在项目运行时,如何更改JFrame背景图像_Java_Swing_Background_Jpanel - Fatal编程技术网

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

Java 在项目运行时,如何更改JFrame背景图像,java,swing,background,jpanel,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.addActionListen

我的背景是

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

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

我认为您应该在更改背景后使用
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();
    }
});

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

对代码的评论:

  • 您正在为一些Swing组件使用静态变量,这表明您应该重新考虑您的设计。只声明有意义的静态是静态的,而SwingGUI组件几乎不属于这一类
  • 当您在使用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));
    }
}
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Image;
导入java.awt.event.ActionEvent;
导入java.io.IOException;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.util.ArrayList;
导入java.util.List;
导入javax.imageio.imageio;
导入javax.swing.AbstractAction;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
@抑制警告(“串行”)
公共类ChangeBackground扩展了JPanel{
公共静态最终字符串根路径=”https://upload.wikimedia.org/wikipedia/commons/thumb/";
公共静态最终字符串[]IMG\u路径={
“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/USCA PitolinDaylight.jpg/640px USCA PitolinDaylight.jpg”,
“9/9a/金门大桥下方.jpeg/640px-金门大桥下方.jpeg”,
“2/29/Eiffel_Tower_(2962488972).jpg/640px-Eiffel_Tower_(2962488972.jpg”,
“8/8楼/圣母院大教堂.jpg/640px-圣母院大教堂.jpg”
};
私有静态最终整型参数W=640;
专用静态最终整型参数参数H=480;
私有列表图像=新的ArrayList();
私有int imageIndex=0;
公共背景(列表图像){
这个。图像=图像;
添加(新的JButton(新的NextImageAction(“下一幅图像”));
}
下一页()的公共作废{
imageIndex++;
imageIndex%=images.size();
重新油漆();
}
@凌驾
公共维度getPreferredSize(){
如果(isPreferredSizeSet()){
返回super.getPreferredSize();
}
返回新维度(PREF_W,PREF_H);
}
私有类NextImageAction扩展了AbstractAction{
public NextImageAction(字符串名称){
超级(姓名);
int助记符=(int)name.charAt(0);
putValue(助记符键,助记符);
}
@凌驾
已执行的公共无效操作(操作事件arg0){
下一代();
}
}
@凌驾
受保护组件(图形g){
超级组件(g);
g、 drawImage(images.get(imageIndex),0,0,this);
}
私有静态void createAndShowGui(最终列表图像){
ChangeBackground主面板=新的ChangeBackground(图像);
JFrame=新JFrame(“变更背景”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(主面板);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
最终列表imgs=new ArrayList();
用于(字符串图像路径:IMG_路径){
imagePath=根路径+imagePath;
试一试{
URL imgUrl=新URL(imagePath);
imgs.add(ImageIO.read(imgUrl));
}捕获(格式错误){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
调用器(()->createAndShowGui(imgs));
}
}
如果单击按钮,然后用光标拖动窗口来调整窗口大小,背景会改变,但所有按钮都会消失

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

我尝试通过执行以下操作来使用按钮更改背景:

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.setContentPane(board2);
board.setIcon( new ImageIcon("img/board.png") );

酷,这解决了背景的问题(我试过