title: JPanel gets repainted several times on resize, sometimes not at all
body: <p>First, some background. I'm building my first GUI app in Java, and I'm not sure if I'm going about it the right way as I'm not familiar with the GUI classes. The end goal is to have a resizeable, zoomable, scrollable map built from Open Street Map data. </p>
  
  <p>What I have right now is a subclass of JPanel I call LinePanel inside a JFrame, and I use the Graphics object to draw lines representing roads. This worked fine for the purpose of checking to see if I'm parsing and interpreting the data correctly, but it seems insufficient and naive. I'm already having an issue where the JPanel gets repainted several times on a resize, causing the map to bug out to the point where my application would need an epilepsy warning. </p>
  
  <p>This is the code I have now: </p>
  
  <pre><code>package map;
  
  import java.awt.BasicStroke;
  import java.awt.BorderLayout;
  import java.awt.Color;
  import java.awt.Graphics2D;
  import java.awt.event.ComponentAdapter;
  import java.awt.event.ComponentEvent;
  
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  
  public class MapDisplay {
      private JFrame frame;
      private LinePanel jpanel;
  
      public MapDisplay(Map map) {
          this.frame = new JFrame();
          frame.setLayout(new BorderLayout());
          frame.addComponentListener(new ComponentAdapter() {
              public void componentResized(ComponentEvent e) {
                  jpanel.repaint();
              }
          });
          jpanel = new LinePanel(map);
          frame.add(jpanel, BorderLayout.CENTER);
      }
  
      public void display() {
          frame.setSize(710, 935);
          frame.setVisible(true);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          jpanel.repaint();
      }
  
      class LinePanel extends JPanel {
          private static final long serialVersionUID = 1965018056953712219L;
          private Map map;
          private int width;
          private int height;
  
          private int latAsY(double lat) {
              return height
                      - (int) (height * (lat - map.getMinLat()) / (map
                              .getMaxLat() - map.getMinLat()));
          }
  
          private int lonAsX(double lon) {
              return (int) (width * (lon - map.getMinLong()) / (map.getMaxLong() - map
                      .getMinLong()));
          }
  
          private void recalculateDimensions() {
              double mapRatio = (map.getMaxLat() - map.getMinLat())
                      / (map.getMaxLong() - map.getMinLong());
              double panelRatio = this.getHeight() / (double) this.getWidth();
              if (mapRatio &gt; panelRatio) {
                  width = (int) (this.getHeight() / mapRatio);
                  height = this.getHeight();
              } else {
                  width = this.getWidth();
                  height = (int) (mapRatio * this.getWidth());
              }
          }
  
          public LinePanel(Map map) {
              super();
              this.map = map;
          }
  
          public void repaint() {
              if (map != null) {
                  recalculateDimensions();
                  Graphics2D g = (Graphics2D) this.getGraphics();
                  if (g != null) {
                      g.setStroke(new BasicStroke(2));
                      g.clearRect(0, 0, jpanel.getWidth(), jpanel.getHeight());
                      g.setColor(Color.WHITE);
                      g.fillRect(0, 0, width, height);
                      g.setColor(Color.BLACK);
                      for (String wayId : map.getWays()) {
                          Way way = map.getWay(wayId);
                          Node prev = null;
                          for (String nodeId : way.getNodes()) {
                              Node cur = map.getNode(nodeId);
                              if (prev != null) {
                                  int y1 = latAsY(prev.getLatitude());
                                  int x1 = lonAsX(prev.getLongitude());
                                  int y2 = latAsY(cur.getLatitude());
                                  int x2 = lonAsX(cur.getLongitude());
                                  g.drawLine(x1, y1, x2, y2);
                              }
                              prev = cur;
                          }
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>I'm calling repaint on resize because It doesn't do that automatically, another sign that I'm doing something wrong. I also clear the JPanel manually with g.fillRect because calling super.repaint() before redrawing the map causes nothing to appear...</p>
  
  <p>Essentially, I'd just like some guidance from more senior Java programmers as to how I should go about this whole endeavor. If I'm on the right track, feel free to just nudge me in the right direction instead of setting me on a new path, but I doubt that this is the case. </p>