/**
   * Moves the column and heading at <code>columnIndex</code> to <code>newIndex</code>. The old
   * column at <code>columnIndex</code> will now be found at <code>newIndex</code>. The column that
   * used to be at <code>newIndex</code> is shifted left or right to make room. This will not move
   * any columns if <code>columnIndex</code> equals <code>newIndex</code>. This method also posts a
   * <code>columnMoved</code> event to its listeners.
   *
   * @param columnIndex the index of column to be moved
   * @param newIndex new index to move the column
   * @exception IllegalArgumentException if <code>column</code> or <code>newIndex</code> are not in
   *     the valid range
   */
  public void moveColumn(int columnIndex, int newIndex) {
    if ((columnIndex < 0)
        || (columnIndex >= getColumnCount())
        || (newIndex < 0)
        || (newIndex >= getColumnCount()))
      throw new IllegalArgumentException("moveColumn() - Index out of range");

    TableColumn aColumn;

    // If the column has not yet moved far enough to change positions
    // post the event anyway, the "draggedDistance" property of the
    // tableHeader will say how far the column has been dragged.
    // Here we are really trying to get the best out of an
    // API that could do with some rethinking. We preserve backward
    // compatibility by slightly bending the meaning of these methods.
    if (columnIndex == newIndex) {
      fireColumnMoved(new TableColumnModelEvent(this, columnIndex, newIndex));
      return;
    }
    aColumn = (TableColumn) tableColumns.elementAt(columnIndex);

    tableColumns.removeElementAt(columnIndex);
    boolean selected = selectionModel.isSelectedIndex(columnIndex);
    selectionModel.removeIndexInterval(columnIndex, columnIndex);

    tableColumns.insertElementAt(aColumn, newIndex);
    selectionModel.insertIndexInterval(newIndex, 1, true);
    if (selected) {
      selectionModel.addSelectionInterval(newIndex, newIndex);
    } else {
      selectionModel.removeSelectionInterval(newIndex, newIndex);
    }

    fireColumnMoved(new TableColumnModelEvent(this, columnIndex, newIndex));
  }
  /**
   * Deletes the <code>column</code> from the <code>tableColumns</code> array. This method will do
   * nothing if <code>column</code> is not in the table's columns list. <code>tile</code> is called
   * to resize both the header and table views. This method also posts a <code>columnRemoved</code>
   * event to its listeners.
   *
   * @param column the <code>TableColumn</code> to be removed
   * @see #addColumn
   */
  public void removeColumn(TableColumn column) {
    int columnIndex = tableColumns.indexOf(column);

    if (columnIndex != -1) {
      // Adjust for the selection
      if (selectionModel != null) {
        selectionModel.removeIndexInterval(columnIndex, columnIndex);
      }

      column.removePropertyChangeListener(this);
      tableColumns.removeElementAt(columnIndex);
      invalidateWidthCache();

      // Post columnAdded event notification.  (JTable and JTableHeader
      // listens so they can adjust size and redraw)
      fireColumnRemoved(new TableColumnModelEvent(this, columnIndex, 0));
    }
  }