protected void loadData(String s) {
    try {
      double[] doubles = parseDoubles(s);

      if (doubles.length != width * height) {
        throw new IOException(
            "File doesn't contain width x height (" + (width * height) + ") values");
      }

      DoubleBuffer buffer = Buffers.newDirectDoubleBuffer(width * height);
      buffer.put(doubles);
      buffer.rewind();

      for (int i = 0; i < width * height; i++) {
        double elev = buffer.get();
        minElevation = Math.min(minElevation, elev);
        maxElevation = Math.max(maxElevation, elev);
      }

      synchronized (elevationLock) {
        this.elevations = buffer;
      }
      // force a recalculate
      lastGlobe = null;
      firePropertyChange(AVKey.LAYER, null, this);
    } catch (IOException e) {
      if (loadAttempts < MAX_DOWNLOAD_ATTEMPTS) {
        loaded = false;
        Downloader.removeCache(url);
        Logging.logger().warning("Deleted corrupt cached data file for " + url);
      } else {
        e.printStackTrace();
      }
    }
  }
 @Override
 public void loadIcon(final Runnable afterLoad) {
   synchronized (iconLock) {
     if (!iconDownloading && !iconLoaded) {
       iconDownloading = true;
       RetrievalHandler setIconHandler =
           new RetrievalHandler() {
             @Override
             public void handle(RetrievalResult result) {
               synchronized (iconLock) {
                 try {
                   Image image = ImageIO.read(result.getAsInputStream());
                   icon = new ImageIcon(image);
                 } catch (Exception e) {
                 }
                 iconLoaded = true;
                 iconDownloading = false;
               }
               afterLoad.run();
             }
           };
       Downloader.downloadIfModified(iconURL, setIconHandler, setIconHandler, true);
     }
   }
 }