/**
   * Creates a {@link DialogComponentTable} with {@code model, pattern, portIndex} parameters.
   *
   * @param model The associated model of the name of new columns.
   * @param pattern The associated pattern model.
   * @param portIndex The port index to check for column matches.
   */
  public DialogComponentTable(
      final SettingsModelStringArray model,
      final SettingsModelString pattern,
      final int portIndex) {
    super(model);
    this.pattern = pattern;
    this.portIndex = portIndex;
    table = new TableView();
    getComponentPanel().add(table);
    table
        .getContentTable()
        .getTableHeader()
        .addMouseListener(
            new MouseAdapter() {
              private volatile long lastAccessTime;

              @SuppressWarnings("synthetic-access")
              @Override
              public void mouseClicked(final MouseEvent e) {
                if (e.getWhen() == this.lastAccessTime || e.getButton() != MouseEvent.BUTTON1) {
                  return;
                }
                this.lastAccessTime = e.getWhen();
                final int column = table.getContentTable().columnAtPoint(e.getPoint());
                final DataTableSpec dataTableSpec =
                    table.getContentTable().getContentModel().getDataTableSpec();
                if (column < singleCount || column >= singleCount + newColumns.size()) {
                  return;
                }
                final DataColumnSpec columnSpec = dataTableSpec.getColumnSpec(column);
                final DataColumnSpecCreator dataColumnSpecCreator =
                    new DataColumnSpecCreator(columnSpec);
                final String newValue = JOptionPane.showInputDialog("New name of the column: ");
                if (newValue != null) {
                  dataColumnSpecCreator.setName(newValue);
                  newColumns.set(column - singleCount, newValue);
                  final DataColumnSpec newColSpec = dataColumnSpecCreator.createSpec();
                  final ReplacedColumnsTable replacedColumnsTable =
                      new ReplacedColumnsTable(
                          table.getContentModel().getDataTable(),
                          newColSpec,
                          column,
                          new ReplacedCellFactory() {
                            @Override
                            public DataCell getReplacement(final DataRow row, final int index) {
                              return row.getCell(index);
                            }
                          });
                  table.setDataTable(replacedColumnsTable);
                }
                e.consume();
              }
            });
  }
 @Override
 public void setToolTipText(final String text) {
   table.setToolTipText(text);
 }
  @Override
  protected void updateComponent() {
    if (beforeLoad) { // This is immediately *after* load!
      newColumns.clear();
      newColumns.addAll(
          Arrays.asList(((SettingsModelStringArray) getModel()).getStringArrayValue()));
      beforeLoad = false; // Never again
    }
    final PortObjectSpec lastTableSpec = getLastTableSpec(portIndex);
    final List<DataRow> dataRows = new ArrayList<DataRow>();
    final List<DataColumnSpec> colSpecs = new ArrayList<DataColumnSpec>();
    if (lastTableSpec instanceof DataTableSpec) {
      final DataTableSpec spec = (DataTableSpec) lastTableSpec;
      try {
        final Map<List<String>, Map<String, Integer>> parts =
            UnpivotNodeModel.createParts(pattern.getStringValue(), spec);
        final Set<Integer> participating = new HashSet<Integer>();
        for (final Map<String, Integer> map : parts.values()) {
          for (final Integer i : map.values()) {
            participating.add(i);
          }
        }
        for (int i = 0; i < spec.getNumColumns(); ++i) {
          if (!participating.contains(Integer.valueOf(i))) {
            colSpecs.add(spec.getColumnSpec(i));
          }
        }
        singleCount = colSpecs.size();
        int rowCount = 0;
        if (parts.isEmpty() || newColumns.size() != parts.keySet().iterator().next().size()) {
          newColumns.clear();
          if (!parts.isEmpty()) { // Fill with defaults
            for (int i = parts.keySet().iterator().next().size(); i-- > 0; ) {
              final String colName = "Col_" + i;
              newColumns.add(colName);
              colSpecs.add(new DataColumnSpecCreator(colName, StringCell.TYPE).createSpec());
            }
          }
        } else {
          for (final String colName : newColumns) {
            colSpecs.add(new DataColumnSpecCreator(colName, StringCell.TYPE).createSpec());
          }
        }
        final Map<String, DataType> types = new LinkedHashMap<String, DataType>();
        for (final Entry<List<String>, Map<String, Integer>> outer : parts.entrySet()) {
          final Map<String, Integer> map = outer.getValue();
          for (final Entry<String, Integer> entry : map.entrySet()) {
            final String colName = entry.getKey();
            final DataType origType = types.get(colName);
            if (origType == null) {
              types.put(colName, spec.getColumnSpec(entry.getValue().intValue()).getType());
            } else {
              types.put(
                  colName,
                  DataType.getCommonSuperType(
                      origType, spec.getColumnSpec(entry.getValue().intValue()).getType()));
            }
          }
        }
        for (final Entry<String, DataType> entry : types.entrySet()) {
          colSpecs.add(new DataColumnSpecCreator(entry.getKey(), entry.getValue()).createSpec());
        }
        for (final Entry<List<String>, Map<String, Integer>> entry : parts.entrySet()) {
          final List<DataCell> cells = new ArrayList<DataCell>(colSpecs.size());
          for (int i = singleCount; i-- > 0; ) {
            cells.add(DataType.getMissingCell());
          }
          for (final String val : entry.getKey()) {
            cells.add(new StringCell(val));
          }
          for (final Entry<String, Integer> inner : entry.getValue().entrySet()) {
            final DataColumnDomain domain =
                spec.getColumnSpec(inner.getValue().intValue()).getDomain();
            cells.add(
                domain.getLowerBound() == null
                    ? domain.getValues() == null || domain.getValues().isEmpty()
                        ? DataType.getMissingCell()
                        : domain.getValues().iterator().next()
                    : domain.getLowerBound());
          }
          dataRows.add(new DefaultRow("Row" + rowCount, cells));
          ++rowCount;
        }
      } catch (final PatternSyntaxException e) {
        for (final DataColumnSpec dataColumnSpec : spec) {
          colSpecs.add(dataColumnSpec);
        }
      }
    }

    @SuppressWarnings("deprecation")
    final DataTable data =
        new org.knime.core.data.def.DefaultTable(
            dataRows.toArray(new DataRow[dataRows.size()]),
            new DataTableSpec(colSpecs.toArray(new DataColumnSpec[colSpecs.size()])));
    table.setDataTable(data);
    table.repaint();
  }
 @Override
 protected void setEnabledComponents(final boolean enabled) {
   table.setEnabled(enabled);
 }