How can I add an image to a panel

后端 未结 3 1714
我寻月下人不归
我寻月下人不归 2021-01-29 16:04

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 p

相关标签:
3条回答
  • 2021-01-29 16:11

    All you need to do is,

    1. Read image file.
    2. Draw image to background with help of Graphics object.

    just replace JPanel panel = new JPanel(); with below code.

             JPanel panel = new JPanel() {
                 @Override
                 protected void paintComponent(Graphics g) {
                     Image image = null;
                     try {
                         image = ImageIO.read(new URL("https://www.google.co.in/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png"));
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
                     super.paintComponent(g);
                     g.drawImage(image, 0, 0, null);
                 }
             };
    
    0 讨论(0)
  • 2021-01-29 16:14

    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.

    0 讨论(0)
  • 2021-01-29 16:19
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JPanel;
    
    public class ImagePanel extends JPanel{
    
        private BufferedImage image;
    
        public ImagePanel() {
           try {                
              image = ImageIO.read(new File("image name and path"));
           } catch (IOException ex) {
                // handle exception...
           }
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this); // see javadoc for more info on the parameters            
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题