protected void spendXP() {
    String skillName = (String) choiceSkill.getSelectedItem();
    if (choiceNoSkill.equals(skillName)) {
      // This shouldn't happen, but guard against it anyway.
      return;
    }
    int rows = personnelTable.getRowCount();
    int improvedPersonnelCount = rows;
    while (rows > 0) {
      for (int i = 0; i < rows; ++i) {
        Person p = personnelModel.getPerson(personnelTable.convertRowIndexToModel(i));
        int cost = 0;
        if (p.hasSkill(skillName)) {
          cost = p.getCostToImprove(skillName);
        } else {
          cost = SkillType.getType(skillName).getCost(0);
        }
        int experience = p.getExperienceLevel(false);

        // Improve the skill and deduce the cost
        p.improveSkill(skillName);
        campaign.personUpdated(p);
        p.setXp(p.getXp() - cost);

        // The next part is bollocks and doesn't belong here, but as long as we hardcode AtB ...
        if (campaign.getCampaignOptions().getUseAtB()) {
          if ((p.getPrimaryRole() > Person.T_NONE)
              && (p.getPrimaryRole() <= Person.T_CONV_PILOT)
              && (p.getExperienceLevel(false) > experience)
              && (experience >= SkillType.EXP_REGULAR)) {
            String spa = campaign.rollSPA(p.getPrimaryRole(), p);
            if (null == spa) {
              if (campaign.getCampaignOptions().useEdge()) {
                p.acquireAbility(
                    PilotOptions.EDGE_ADVANTAGES, "edge", p.getEdge() + 1); // $NON-NLS-1$
                p.addLogEntry(
                    campaign.getDate(),
                    String.format(resourceMap.getString("gainedEdge.text"))); // $NON-NLS-1$
              }
            } else {
              p.addLogEntry(
                  campaign.getDate(),
                  String.format(resourceMap.getString("gained.format"), spa)); // $NON-NLS-1$
            }
          }
        }
      }
      // Refresh the filter and continue if we still have anyone available
      updatePersonnelTable();
      rows = personnelTable.getRowCount();
      dataChanged = true;
    }
    if (improvedPersonnelCount > 0) {
      campaign.addReport(
          String.format(
              resourceMap.getString("improvedSkills.format"),
              skillName,
              improvedPersonnelCount)); //$NON-NLS-1$
    }
  }
  private JComponent getPersonnelTable() {
    personnelTable = new JTable(personnelModel);
    personnelTable.setCellSelectionEnabled(false);
    personnelTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);

    for (int i = PersonnelTableModel.N_COL - 1; i >= 0; --i) {
      TableColumn column = personnelTable.getColumnModel().getColumn(i);
      if (personnelColumns.contains(Integer.valueOf(i))) {
        column.setPreferredWidth(personnelModel.getColumnWidth(i));
        column.setCellRenderer(new CellRenderer());
      } else {
        personnelTable.removeColumn(column);
      }
    }
    personnelTable.setIntercellSpacing(new Dimension(1, 0));
    personnelTable.setShowGrid(false);
    personnelTable.setRowSorter(personnelSorter);

    JScrollPane pane = new JScrollPane(personnelTable);
    pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    return pane;
  }
  public BatchXPDialog(JFrame parent, Campaign campaign) {
    super(parent, "", true); // $NON-NLS-1$

    this.resourceMap =
        ResourceBundle.getBundle(
            "mekhq.resources.BatchXPDialog", new EncodeControl()); // $NON-NLS-1$

    setTitle(resourceMap.getString("dialogue.title")); // $NON-NLS-1$
    choiceNoSkill = resourceMap.getString("skill.choice.text"); // $NON-NLS-1$

    this.campaign = Objects.requireNonNull(campaign);
    this.personnelModel = new PersonnelTableModel(campaign);
    personnelModel.refreshData();
    personnelSorter = new TableRowSorter<PersonnelTableModel>(personnelModel);
    personnelSorter.setSortsOnUpdates(true);
    personnelSorter.setComparator(PersonnelTableModel.COL_RANK, new RankSorter(campaign));
    personnelSorter.setComparator(PersonnelTableModel.COL_AGE, new FormattedNumberSorter());
    personnelSorter.setComparator(PersonnelTableModel.COL_XP, new FormattedNumberSorter());
    personnelSorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(1, SortOrder.ASCENDING)));
    personnelFilter = new PersonnelFilter();
    personnelSorter.setRowFilter(personnelFilter);

    initComponents();
  }