如何将图像添加到面板 [英] How can I add an image to a panel

查看:37
本文介绍了如何将图像添加到面板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

edit//我的问题比另一个简单,所以请在这里回答.另一个问题看起来太复杂了,我无法理解.

我想将图像添加到面板,但不确定它是如何完成的.我不想在设计页面上这样做,因为我没有设计我的面板,我只是对其进行了编码以显示出来.那么有谁知道我需要为图像添加什么代码才能显示在那里?我在哪里保存图像以便可以包含它.这是我到目前为止所做的代码

JFrame frame = new JFrame("JButton");frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(500,200);JPanel 面板 = new JPanel();框架.添加(面板);JButton button = new JButton("London");面板添加(按钮);JLabel label = new JLabel("点击", JLabel.CENTER);

解决方案

好的,有两种方法可以添加图片:

  1. 通过覆盖

    但是...如果我们调整窗口大小,我们会得到:

    我更喜欢自定义绘画方法,但这取决于您的需求和喜好.

    产生上述输出的代码是:

    import java.awt.BorderLayout;导入 java.awt.Color;导入 java.awt.Dimension;导入 java.awt.Graphics;导入 java.awt.Image;导入 java.io.IOException;导入 java.net.MalformedURLException;导入 java.net.URL;导入 javax.imageio.ImageIO;导入 javax.swing.BorderFactory;导入 javax.swing.BoxLayout;导入 javax.swing.ImageIcon;导入 javax.swing.JButton;导入 javax.swing.JFrame;导入 javax.swing.JLabel;导入 javax.swing.JPanel;导入 javax.swing.SwingUtilities;公共类 JPanelWithBackgroundImageExample {私人 JFrame 框架;//我们的窗口私人 JPanel 面板;//我们要绘制背景图像的面板私人形象形象;公共静态无效主(字符串 [] args){SwingUtilities.invokeLater(new Runnable() {@覆盖公共无效运行(){新的 JPanelWithBackgroundImageExample().createAndShowGui();}});}公共无效 createAndShowGui() {frame = new JFrame(getClass().getSimpleName());尝试 {image = ImageIO.read(new URL("https://i.stack.imgur.com/XZ4V5.jpg"));//我们从网上读取图片} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}panel = new JPanel() {//我们需要打开大括号,这样我们才能改变JPanel的默认行为/** 此方法是绘制背景的方法,默认为灰色,* 所以,我们需要告诉它绘制图像.(这个方法已经属于JPanel了,所以我们需要添加* "@Override" 在它之前,所以编译器知道我们正在覆盖它*/@覆盖受保护的无效paintComponent(图形g){super.paintComponent(g);//永远不要忘记这条线,否则你可能会破坏油漆链/** 该方法属于Graphics类,绘制图像,这就是我们希望JPanel作为我们的背景绘制的* 参数为:要绘制的图像、起始位置(x,y)坐标、宽高和观察者*/g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);}/** 此方法是 JPanel 的一部分,我们覆盖它的首选大小并返回我们想要的大小*/@覆盖公共维度 getPreferredSize() {返回新维度(300, 200);}};JLabel label = new JLabel(new ImageIcon(image));//我们创建一个 JLabel 来作为我们组件的容器panel.setBorder(BorderFactory.createLineBorder(Color.WHITE));//我们创建一个边框只是为了两种方式的可见性label.setBorder(BorderFactory.createLineBorder(Color.WHITE));//我们创建一个边框只是为了两种方式的可见性label.setLayout(new BoxLayout(label, BoxLayout.PAGE_AXIS));//我们为标签设置布局管理器label.add(new JLabel("我是标签内的标签"));//我们为我们的标签添加一个新标签(充当容器)label.add(new JButton("我是标签内的按钮"));//我们向标签添加一个按钮(充当容器)//您可以像往常一样将组件添加到面板panel.add(new JButton("嘿!我是一个按钮!"));//我们在jpanel上添加一个按钮panel.add(new JLabel("点击我旁边的按钮!:D"));//我们给jpanel添加一个标签frame.add(panel, BorderLayout.WEST);//我们将大小为 300 x 200 的窗格添加到 JFrame 的左侧部分frame.add(label, BorderLayout.EAST);//我们将标签(充当容器/jpanel)添加到我们JFrame的右侧部分框架.pack();//我们打包框架,因此它采用其首选大小(因为我们只向其中添加了一个组件(JPanel)//由于面板的大小为300 x 200,因此框架也将具有此大小frame.setVisible(true);//我们设置框架的可见性frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}

    现在,作为一般提示,将您的程序放在 事件上调度线程 (EDT) 通过如下更改 main() 方法:

    public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {@覆盖公共无效运行(){//你的构造函数在这里}});}

    现在,在评论中回答您的问题:

    <块引用>

    除了图像,一切正常,因为我没有那个图像.所以我从谷歌复制了一个图片网址并将其粘贴进去,但它没有出现?我能做什么

    好吧,我认为您从链接的答案中获取了代码并更改了这一行:

    frame.setContentPane(new JLabel(new ImageIcon("C:/Users/Frakcool/workspace/StackOverflowProjects/src/test/Air.jpg")));

    这样的事情:

    frame.setContentPane(new JLabel(new ImageIcon("https://i.stack.imgur.com/XZ4V5.jpg")));

    在那种情况下,很明显代码不会那样工作,Swing 不知道如何解释字符串中的 http,但是 URL 类确实如此,因此,您应该将上面的行更改为:

    frame.setContentPane(new JLabel(new ImageIcon(new URL("https://i.stack.imgur.com/XZ4V5.jpg"))));

    并导入:

    import java.net.URL;

    在你的课堂上.

    我希望这有助于您理解代码的工作原理,如果不能,那么我认为您需要付出更多努力来理解它.

    edit// my question is simpler than the other one so please just answer here. the other question looks too complicated for me to understand.

    I want to add an image to a panel, but not sure how it's done. I don't want to do it from the design page because I didn't Design my panel I only coded it to show up. so does anyone know what code I need to add for an image to show up on there? and where do I save the image so that it can be included. here is the code I've done so far

    JFrame frame = new JFrame("JButton");
    
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(500,200);
    JPanel panel = new JPanel();
    frame.add(panel);
    
    JButton button = new JButton("London"); 
    panel.add(button); 
    
    JLabel label = new JLabel("Click", JLabel.CENTER);
    

    解决方案

    Alright, there are 2 ways to add your image:

    1. Using custom painting by overriding JPanel#paintComponent(...) method.

    2. Using a JLabel to display the image and applying to it various layout managers to get the desired GUI.


    I'm going to expand on how to use the 1st way with some comments in the code, the original idea was given in this answer so, be sure to give credits to the author.

    You need to either:

    • Create a custom JPanel object
    • Create a class that extends JPanel

    In any case you need to override the paintComponent(...) method.

    Later, in that paintComponent() method you need to draw the image using Graphics#drawImage(...) method. This will make the JPanel to draw the image as the background.

    After that you should override your JPanel's getPreferredSize() method, so you can call JFrame#pack(), which will resize your JFrame's size to its preferred size (which is the minimum size where all your components are visible).

    After doing that, you can easily add components as you've always done:

    panel.add(...);
    

    And the second way is to make a JLabel to act as a Container, where you can add more Components to it (just like you do in a JPanel) (As shown in this answer)

    The way to do this is:

    • Create a JLabel with an ImageIcon
    • Set its layout manager
    • Add components to it

    Depending on which one you choose you have some differences:

    • Using the custom painting option, you need to take care of the preferred size of your container but you have more control over your component. However the image will fill all the space available on the window.
    • Using the JLabel option you can simply call pack() on your JFrame and it will resize to the image size, but if your image is too big your JFrame will be the same size too. If you resize your window to be shorter the image will be cropped and show "white" space if you make your window bigger.

    This is how the image looks like with the 2 options, on the left the custom painting, on the right the label approach. At first they both look the same...

    But... If we resize the window, this is what we get:

    I like the custom painting approach more, but it depends on your needs and likes.

    The code that produces the above output is:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.imageio.ImageIO;
    import javax.swing.BorderFactory;
    import javax.swing.BoxLayout;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class JPanelWithBackgroundImageExample {
    
        private JFrame frame; //Our window
        private JPanel panel; //The panel where we're going to draw the background image
        private Image image;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new JPanelWithBackgroundImageExample().createAndShowGui();
                }
            });
        }
    
        public void createAndShowGui() {
            frame = new JFrame(getClass().getSimpleName());
    
            try {
                image = ImageIO.read(new URL("https://i.stack.imgur.com/XZ4V5.jpg")); //We read the image from the Internet
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            panel = new JPanel() { //We need to open the curly braces so we can change the default behavior of the JPanel
                /* 
                 * This method is the one that paints the background, by default it paints it with gray color,
                 * so, we need to tell it to draw an image instead. (This method belongs to JPanel already, so we need to add
                 * "@Override" before it, so the compiler knows we're overriding it
                 */
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g); //Never forget this line or you could break the paint chain
    
                    /* 
                     * This method belongs to the Graphics class and draws an image, this is what we want the JPanel to draw as our background
                     * The parameters are: the image to be drawn, the starting position (x, y) coords, the width and height and the observer
                     */
                    g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);
                }
    
                /* 
                 * This method is part of the JPanel, we're overriding it's preferred size and return the size we want
                 */
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(300, 200);
                }
            };
    
            JLabel label = new JLabel(new ImageIcon(image)); //We create a JLabel that will act as a container for our components
    
            panel.setBorder(BorderFactory.createLineBorder(Color.WHITE)); //We create a border just for visibility of both ways
            label.setBorder(BorderFactory.createLineBorder(Color.WHITE)); //We create a border just for visibility of both ways
    
            label.setLayout(new BoxLayout(label, BoxLayout.PAGE_AXIS)); //We set the layout manager for the label
    
            label.add(new JLabel("I'm a label inside a label")); //We add a new label to our label (that is acting as a container)
            label.add(new JButton("I'm a button inside a label")); //We add a button to our label (that is acting as a container)
    
            //You can add your components to the panel, as you always do it
            panel.add(new JButton("HEY! I'm a button!")); //We add a button to our jpanel
            panel.add(new JLabel("Click the button next to me! :D")); //We add a label to our jpanel
    
            frame.add(panel, BorderLayout.WEST); //We add the pane which has a size of 300 x 200 to the left part of our JFrame
            frame.add(label, BorderLayout.EAST); //We add the label (which acts as a container / jpanel) to the right part of our JFrame
            frame.pack(); //We pack the frame, so it takes its preferred size (and as we only added a single component to it (the JPanel)
                            //As the panel has a size of 300 x 200, the frame will also have this size
            frame.setVisible(true); //We set the visibility of the frame
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }
    

    Now, as a general tip, place your program on the Event Dispatch Thread (EDT) by changing your main() method as follows:

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //Your constructor here
            }
        });
    }
    

    And now, to answer your question in the comments:

    everything works except the image because I don't have that image. so I copied an image url from google and pasted it in and it didn't appear? what can I do

    Well, I think you took the code from the linked answer and changed this line:

    frame.setContentPane(new JLabel(new ImageIcon("C:/Users/Frakcool/workspace/StackOverflowProjects/src/test/Air.jpg")));
    

    To something like this:

    frame.setContentPane(new JLabel(new ImageIcon("https://i.stack.imgur.com/XZ4V5.jpg")));
    

    Well in that case, it's obvious that the code won't work that way, Swing doesn't know how to interpret a http in a String, but URL class does, and thus, you should change the above line like:

    frame.setContentPane(new JLabel(new ImageIcon(new URL("https://i.stack.imgur.com/XZ4V5.jpg"))));
    

    And import:

    import java.net.URL;
    

    In your class.

    I hope this helps you in understanding how the code works, if not, well, I think you need to put more effort in understanding it.

    这篇关于如何将图像添加到面板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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