title: How to load background image into JPanel dynamically?
body: <p>I have a swing gui application. I want to type into a image path and then click button to load the image into a jpanel. The problem is it won't be loaded, but if I add the extended jpanel which is able to load image when I instiate the jframe, image can be loaded normally. why is that?</p>
  
  <p>code related:</p>
  
  <pre><code>package com.xdg.graphic;
  
  import java.awt.Dimension;
  import java.awt.Graphics;
  import java.awt.image.BufferedImage;
  import java.io.File;
  import java.io.IOException;
  
  import javax.imageio.ImageIO;
  import javax.swing.JPanel;
  
  public class ImageLoader extends JPanel {
      private String imgPath;
      private BufferedImage image;
  
  
      public ImageLoader(String imgPath) {
          this.imgPath = imgPath;
          try {
              this.image=ImageIO.read(new File(imgPath));
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  
      public void paint(Graphics g) {
          g.drawImage(image, 0, 0, null);
      }
  
      @Override
      protected void paintComponent(Graphics g) {
          g.drawImage(image, 0, 0, null);
      }
  
      public Dimension getPreferredSize() {
          if (image == null) {
               return new Dimension(100,100);
          } else {
             return new Dimension(image.getWidth(null), image.getHeight(null));
         }
      }
  
      public String getImgPath() {
          return imgPath;
      }
  
      public void setImgPath(String imgPath) {
          this.imgPath = imgPath;
      }
  
  
  
  }
  </code></pre>
  
  <p>invoker class:</p>
  
  <pre><code>package com.xdg.image;
  
  import com.xdg.graphic.ImageLoader;
  import sun.awt.windows.ThemeReader;
  
  import java.awt.*;
  
  public class FrmImgCropper extends javax.swing.JFrame {
      private ImageLoader imageLoader;
  
      /** Creates new form FrmImgCropper */
      public FrmImgCropper() {
          initComponents();
      }
  
      /** This method is called from within the constructor to
       * initialize the form.
       * WARNING: Do NOT modify this code. The content of this method is
       * always regenerated by the Form Editor.
       */
      //GEN-BEGIN:initComponents
      // &lt;editor-fold defaultstate="collapsed" desc="Generated Code"&gt;
      private void initComponents() {
  
          jPanel2 = new javax.swing.JPanel();
          tfImagePath = new javax.swing.JTextField();
          btnPreview = new javax.swing.JButton();
          tfRatioW = new javax.swing.JTextField();
          tfRatioH = new javax.swing.JTextField();
          jLabel1 = new javax.swing.JLabel();
          btnLoad = new javax.swing.JButton();
          jLabel2 = new javax.swing.JLabel();
  
          setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  
          btnPreview.setText("Preview");
  
          jLabel1.setText(":");
  
          btnLoad.setText("Load");
          btnLoad.addActionListener(new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                  btnLoadActionPerformed(evt);
              }
          });
  
          jLabel2.setText("Image Path:");
  
          javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
          jPanel2.setLayout(jPanel2Layout);
          jPanel2Layout.setHorizontalGroup(jPanel2Layout
                  .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(
                          jPanel2Layout
                                  .createSequentialGroup()
                                  .addGap(34, 34, 34)
                                  .addComponent(tfRatioW, javax.swing.GroupLayout.PREFERRED_SIZE, 55,
                                          javax.swing.GroupLayout.PREFERRED_SIZE)
                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                  .addComponent(jLabel1)
                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                  .addComponent(tfRatioH, javax.swing.GroupLayout.PREFERRED_SIZE, 53,
                                          javax.swing.GroupLayout.PREFERRED_SIZE)
                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 123,
                                          Short.MAX_VALUE)
                                  .addComponent(btnLoad, javax.swing.GroupLayout.PREFERRED_SIZE, 82,
                                          javax.swing.GroupLayout.PREFERRED_SIZE).addGap(46, 46, 46)
                                  .addComponent(btnPreview).addGap(276, 276, 276))
                  .addGroup(
                          jPanel2Layout.createSequentialGroup().addGap(66, 66, 66).addComponent(jLabel2)
                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                  .addComponent(tfImagePath, javax.swing.GroupLayout.DEFAULT_SIZE, 593, Short.MAX_VALUE)
                                  .addGap(29, 29, 29)));
          jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(
                          javax.swing.GroupLayout.Alignment.TRAILING,
                          jPanel2Layout
                                  .createSequentialGroup()
                                  .addContainerGap(20, Short.MAX_VALUE)
                                  .addGroup(
                                          jPanel2Layout
                                                  .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                  .addComponent(jLabel2)
                                                  .addComponent(tfImagePath, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                          javax.swing.GroupLayout.DEFAULT_SIZE,
                                                          javax.swing.GroupLayout.PREFERRED_SIZE))
                                  .addGap(18, 18, 18)
                                  .addGroup(
                                          jPanel2Layout
                                                  .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                  .addComponent(jLabel1)
                                                  .addComponent(tfRatioW, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                          javax.swing.GroupLayout.DEFAULT_SIZE,
                                                          javax.swing.GroupLayout.PREFERRED_SIZE)
                                                  .addComponent(tfRatioH, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                          javax.swing.GroupLayout.DEFAULT_SIZE,
                                                          javax.swing.GroupLayout.PREFERRED_SIZE)
                                                  .addComponent(btnPreview).addComponent(btnLoad)).addGap(20, 20, 20)));
  
          getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);
  
          pack();
      }// &lt;/editor-fold&gt;
      //GEN-END:initComponents
  
      private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {
          if (imageLoader == null) {
              imageLoader = new ImageLoader(tfImagePath.getText());
              imageLoader.setBackground(Color.green);
  
              getContentPane().add(imageLoader, BorderLayout.CENTER);
              getContentPane().repaint();
              this.repaint();//image does not show up this way dnamically
          } else {
              imageLoader.setImgPath(tfImagePath.getText());
              imageLoader.repaint();
          }
  
      }
  
      /**
       * @param args the command line arguments
       */
      public static void main(String args[]) {
          java.awt.EventQueue.invokeLater(new Runnable() {
              public void run() {
  
                  FrmImgCropper cropper = new FrmImgCropper();
                  cropper.getContentPane().add(new ImageLoader("i:\\temp4\\car.jpg"));  //if I add the image loader here directly,image shows up
                  cropper.setSize(800, 900);
                  cropper.setVisible(true);
              }
          });
      }
  
      //GEN-BEGIN:variables
      // Variables declaration - do not modify
      private javax.swing.JButton btnLoad;
      private javax.swing.JButton btnPreview;
      private javax.swing.JLabel jLabel1;
      private javax.swing.JLabel jLabel2;
      private javax.swing.JPanel jPanel2;
      private javax.swing.JTextField tfImagePath;
      private javax.swing.JTextField tfRatioH;
      private javax.swing.JTextField tfRatioW;
      // End of variables declaration//GEN-END:variables
  
  }
  </code></pre>
  
  <p>any ideas? I've been working on it two hours.</p>