private static void saveBookmarks(JTable table) {
    BookmarksTableModel btm = (BookmarksTableModel) table.getModel();
    List<Bookmark> bookmarks = btm.getData();

    // get the path (null if none selected)
    File selectedFile = DialogUtils.chooseFileForSave("Save Bookmarks", "Bookmarks.txt");

    // set the genome
    if (selectedFile != null) {
      try {
        saveBookmarks(selectedFile.getAbsolutePath(), bookmarks);
      } catch (IOException ex) {
        DialogUtils.displayError("Error", "Unable to save bookmarks: " + ex.getMessage());
      }
    }
  }
  private void loadBookmarks(JTable table) {
    final BookmarksTableModel btm = (BookmarksTableModel) table.getModel();
    List<Bookmark> bookmarks = btm.getData();

    if (bookmarks.size() > 0) {
      String message = "Clear existing bookmarks?";
      String title = "Clear Bookmarks";
      // display the JOptionPane showConfirmDialog
      int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
      if (reply == JOptionPane.YES_OPTION) {
        btm.clearData();
        BookmarkController.getInstance().clearBookmarks();
      }
    }

    final File selectedFile = DialogUtils.chooseFileForOpen("Load Bookmarks", null, null);

    // set the genome
    if (selectedFile != null) {

      int result =
          JOptionPane.showOptionDialog(
              null,
              "Would you like to add padding to each bookmark range?",
              "Add a margin?",
              JOptionPane.YES_NO_OPTION,
              JOptionPane.QUESTION_MESSAGE,
              null,
              null,
              null);
      final boolean addMargin = (result == JOptionPane.YES_OPTION);

      Window w = SwingUtilities.getWindowAncestor(BookmarkSheet.this);
      JOptionPane optionPane =
          new JOptionPane(
              "<html>Loading bookmarks from file.<br>This may take a moment.</html>",
              JOptionPane.INFORMATION_MESSAGE,
              JOptionPane.CANCEL_OPTION);
      final JDialog dialog = new JDialog(w, "Loading Bookmarks", Dialog.ModalityType.MODELESS);
      dialog.setContentPane(optionPane);
      dialog.pack();
      dialog.setLocationRelativeTo(w);
      dialog.setVisible(true);
      new Thread("BookmarkSheet.loadBookmarks") {
        @Override
        public void run() {
          try {
            BookmarkController.getInstance().addBookmarksFromFile(selectedFile, addMargin);
            btm.fireTableDataChanged();
          } catch (Exception ex) {
            DialogUtils.displayError("Error", "Unable to load bookmarks: " + ex.getMessage());
          } finally {
            dialog.setVisible(false);
            dialog.dispose();
          }
        }
      }.start();
    }
  }
 private void cancelButtonActionPerformed(
     java.awt.event.ActionEvent evt) { // GEN-FIRST:event_cancelButtonActionPerformed
   if (DialogUtils.askYesNo("Confirm Cancel", "Are you sure you want to cancel?")
       == DialogUtils.YES) {
     formatter.cancel();
     dispose();
   }
 } // GEN-LAST:event_cancelButtonActionPerformed
 @Override
 public void handleEvent(FormatEvent event) {
   switch (event.getType()) {
     case PROGRESS:
       progressBar.setValue((int) (event.getProgress() * 100.0));
       if (event.getSubTask() != null) {
         statusLabel.setText(event.getSubTask());
       }
       break;
     case COMPLETED:
       setVisible(false);
       if (GenomeController.getInstance().isGenomeLoaded()) {
         if (formatter instanceof BAMToCoverage) {
           // For coverage tracks, we report success, but don't offer to open the track.
           DialogUtils.displayMessage(
               "Format Successful",
               String.format(
                   "<HTML>Format successful.<BR>Coverage will be available the next time you open <i>%s</i>.</HTML>",
                   formatter.getInputFile().getName()));
         } else {
           if (toLoadTrack
               || DialogUtils.askYesNo("Format Successful", "Format successful. Open track now?")
                   == DialogUtils.YES) {
             try {
               FrameController.getInstance()
                   .addTrackFromPath(formatter.getOutputFile().getAbsolutePath(), null, null);
             } catch (Exception ex) {
             }
           }
         }
       } else {
         DialogUtils.displayMessage(
             "Format Successful",
             "<HTML>Format successful. <BR>A genome must be loaded before you can open this track.</HTML>");
       }
       break;
     case FAILED:
       setVisible(false);
       SavantFileFormatter.reportFormattingError(event.getError(), formatter.getInputFile());
       break;
   }
 }