public static int fillDataTable(
      SimpleDataTable dataTable,
      Map<String, double[]> lastPopulation,
      Population pop,
      boolean drawDominated) {
    lastPopulation.clear();
    dataTable.clear();
    int numberOfCriteria = 0;
    for (int i = 0; i < pop.getNumberOfIndividuals(); i++) {
      boolean dominated = false;
      if (!drawDominated) {
        for (int j = 0; j < pop.getNumberOfIndividuals(); j++) {
          if (i == j) continue;
          if (NonDominatedSortingSelection.isDominated(pop.get(i), pop.get(j))) {
            dominated = true;
            break;
          }
        }
      }

      if (drawDominated || (!dominated)) {
        StringBuffer id = new StringBuffer(i + " (");
        PerformanceVector current = pop.get(i).getPerformance();
        numberOfCriteria = Math.max(numberOfCriteria, current.getSize());
        double[] data = new double[current.getSize()];
        for (int d = 0; d < data.length; d++) {
          data[d] = current.getCriterion(d).getFitness();
          if (d != 0) id.append(", ");
          id.append(Tools.formatNumber(data[d]));
        }
        id.append(")");
        dataTable.add(new SimpleDataTableRow(data, id.toString()));
        double[] weights = pop.get(i).getWeights();
        double[] clone = new double[weights.length];
        System.arraycopy(weights, 0, clone, 0, weights.length);
        lastPopulation.put(id.toString(), clone);
      }
    }
    return numberOfCriteria;
  }
 /**
  * Returns true if the second performance vector is better in all fitness criteria than the first
  * one (remember: the criteria should be maximized).
  */
 public static boolean isDominated(AggregationIndividual i1, AggregationIndividual i2) {
   PerformanceVector pv1 = i1.getPerformance();
   PerformanceVector pv2 = i2.getPerformance();
   double[][] performances = new double[pv1.getSize()][2];
   for (int p = 0; p < performances.length; p++) {
     performances[p][0] = pv1.getCriterion(p).getFitness();
     performances[p][1] = pv2.getCriterion(p).getFitness();
   }
   boolean dominated = true;
   for (int p = 0; p < performances.length; p++) {
     dominated &= (performances[p][1] >= performances[p][0]);
   }
   boolean oneActuallyBetter = false;
   for (int p = 0; p < performances.length; p++) {
     oneActuallyBetter |= (performances[p][1] > performances[p][0]);
   }
   dominated &= oneActuallyBetter;
   return dominated;
 }
  public PerformanceVectorViewer(
      final PerformanceVector performanceVector, final IOContainer container) {
    setLayout(new BorderLayout());

    // all criteria
    final CardLayout cardLayout = new CardLayout();
    final JPanel mainPanel = new JPanel(cardLayout);
    add(mainPanel, BorderLayout.CENTER);
    List<String> criteriaNameList = new LinkedList<>();
    for (int i = 0; i < performanceVector.getSize(); i++) {
      PerformanceCriterion criterion = performanceVector.getCriterion(i);
      criteriaNameList.add(criterion.getName());
      JPanel component =
          ResultDisplayTools.createVisualizationComponent(
              criterion, container, "Performance Criterion", false);
      JScrollPane criterionPane = new ExtendedJScrollPane(component);
      criterionPane.setBorder(null);
      criterionPane.setBackground(Colors.WHITE);
      mainPanel.add(criterionPane, criterion.getName());
    }
    if (criteriaNameList.isEmpty()) {
      remove(mainPanel);
      add(new ResourceLabel("result_view.no_criterions"));
      return;
    }
    String[] criteriaNames = new String[criteriaNameList.size()];
    criteriaNameList.toArray(criteriaNames);

    // selection list
    final JList<String> criteriaList =
        new JList<String>(criteriaNames) {

          private static final long serialVersionUID = 3031125186920370793L;

          @Override
          public Dimension getPreferredSize() {
            Dimension dim = super.getPreferredSize();
            dim.width = Math.max(150, dim.width);
            return dim;
          }
        };
    criteriaList.setCellRenderer(new CriterionListCellRenderer());
    criteriaList.setOpaque(false);

    criteriaList.setBorder(BorderFactory.createTitledBorder("Criterion"));
    criteriaList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    criteriaList.addListSelectionListener(
        new ListSelectionListener() {

          @Override
          public void valueChanged(ListSelectionEvent e) {
            String selected = criteriaList.getSelectedValue();
            cardLayout.show(mainPanel, selected);
          }
        });

    JScrollPane listScrollPane = new ExtendedJScrollPane(criteriaList);
    listScrollPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 2));
    add(listScrollPane, BorderLayout.WEST);

    // select first criterion
    criteriaList.setSelectedIndices(new int[] {0});
  }