title: Laggy window when displaying images for the first time with JScrollPane
body: <p>I am trying to display a bunch of ImagePanels in a JScrollPane. The problem with this application is that every time a new row of panels enters the viewport the whole window freezes for a small amount of time. Once scrolled through to the end though, the window will not lag again.</p>
  
  <p>What is the cause of this lagging and how can I prevent it from happening in the first place?</p>
  
  <p>My guess is the panels don't get painted until they are scrolled to. So I tried to call repaint on them after adding them to the background but that didn't work :(</p>
  
  <p>MainClass.java:</p>
  
  <pre><code>import javax.swing.SwingUtilities;
  
  public class MainClass {
  
      public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                  MainFrame frame = new MainFrame();
              }
          });
      }
  }
  </code></pre>
  
  <p>MainFrame.java:</p>
  
  <pre><code>import java.awt.*;
  import javax.swing.*;
  
  public class MainFrame extends JFrame {
  
      private static final long serialVersionUID = -254980289568295701L;
  
      public MainFrame() {
  
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          setExtendedState(JFrame.MAXIMIZED_BOTH);
  
          JPanel background = new JPanel();
          JScrollPane scrollPane = new JScrollPane(background,
                   JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                   JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
          ImagePanel ipanel;
  
          background.setPreferredSize(new Dimension(this.getWidth(),
                                                this.getHeight() + 3000));    
  
          scrollPane.setOpaque(false);
          scrollPane.getViewport().setOpaque(false);
          scrollPane.getVerticalScrollBar().setUnitIncrement(20);
          add(scrollPane);
  
          for (int i = 0; i &lt; 40; i++) {
              ipanel = new ImagePanel();
              ipanel.setPreferredSize(new Dimension(300, 400));
              ipanel.setSize(new Dimension(300, 400));
  
              background.add(ipanel);
          }
  
          setVisible(true);
      }
  }
  </code></pre>
  
  <p>ImagePanel.java:</p>
  
  <pre><code>import java.awt.*;
  import javax.swing.JPanel;
  import java.awt.image.BufferedImage;
  
  public class ImagePanel extends JPanel {
  
      private static final long serialVersionUID = 1997246878999790104L;
      private Image image;
      private int width;
      private int height;
  
      public ImagePanel() {
      width = 300;
      height = 400;
      BufferedImage bufferedImage = new BufferedImage(2000, 2000, BufferedImage.TYPE_INT_RGB);
      Graphics2D g2d = bufferedImage.createGraphics();
      g2d.setColor(Color.white);
      g2d.fillRect(0, 0, 2000, 2000);
      g2d.setColor(Color.black);
      g2d.fillOval(0, 0, 2000, 2000);
      g2d.setColor(Color.yellow);
      g2d.fillOval(1500, 300, 400, 400);
      g2d.fillOval(1200, 600, 400, 400);
      g2d.fillOval(900, 900, 400, 400);
      g2d.fillOval(600, 1200, 400, 400);
      g2d.fillOval(300, 1500, 400, 400);
      g2d.dispose();
      image = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
      }
  
      @Override
      protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          g.drawImage(image, 0, 0, this);
      }
  }
  </code></pre>