@Override
 public boolean importData(TransferHandler.TransferSupport info) {
   JTable target = (JTable) info.getComponent();
   JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation();
   int rowTo = dl.getRow();
   int max = table.getModel().getRowCount();
   if ((rowTo < 0) || (rowTo > max)) {
     rowTo = max;
   }
   target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
   try {
     Integer rowFrom = (Integer) info.getTransferable().getTransferData(localObjectFlavor);
     if (rowTo > rowFrom) {
       rowTo--;
     }
     if ((rowFrom != -1) && (rowFrom != rowTo)) {
       StateTableModel stateTableModel = (StateTableModel) table.getModel();
       stateTableModel.reorder(rowFrom, rowTo);
       target.getSelectionModel().addSelectionInterval(rowTo, rowTo);
       return true;
     }
   } catch (Exception e) {
     e.printStackTrace();
   }
   return false;
 }
  /**
   * Get the vertical drop line rectangle.
   *
   * @param loc the drop location.
   * @return the rectangle.
   */
  private Rectangle getVDropLineRect(JTable.DropLocation loc) {
    if (!loc.isInsertColumn()) {
      return null;
    }

    boolean ltr = table.getComponentOrientation().isLeftToRight();
    int col = loc.getColumn();
    Rectangle rect = table.getCellRect(loc.getRow(), col, true);

    if (col >= table.getColumnCount()) {
      col--;
      rect = table.getCellRect(loc.getRow(), col, true);
      if (ltr) {
        rect.x = rect.x + rect.width;
      }
    } else if (!ltr) {
      rect.x = rect.x + rect.width;
    }

    if (rect.x == 0) {
      rect.x = -1;
    } else {
      rect.x -= 2;
    }

    rect.width = 3;

    return rect;
  }
  /**
   * Get the horizontal drop line rectangle.
   *
   * @param loc the drop location.
   * @return the rectangle.
   */
  private Rectangle getHDropLineRect(JTable.DropLocation loc) {
    if (!loc.isInsertRow()) {
      return null;
    }

    int row = loc.getRow();
    int col = loc.getColumn();

    if (col >= table.getColumnCount()) {
      col--;
    }

    Rectangle rect = table.getCellRect(row, col, true);

    if (row >= table.getRowCount()) {
      row--;
      Rectangle prevRect = table.getCellRect(row, col, true);

      rect.y = prevRect.y + prevRect.height;
    }

    if (rect.y == 0) {
      rect.y = -1;
    } else {
      rect.y -= 2;
    }

    rect.height = 3;

    return rect;
  }
 @Override
 public boolean doHighlight(final ExtTable<?> extTable, final int row) {
   final DropLocation dl = extTable.getDropLocation();
   if (dl == null) {
     return false;
   }
   final JTable.DropLocation dl2 = dl;
   if (dl2.isInsertRow()) {
     return false;
   }
   return dl.getRow() == row;
 }
  /**
   * Paint the drop lines, if any.
   *
   * @param context the Synth context.
   * @param g the Graphics context.
   */
  private void paintDropLines(SeaGlassContext context, Graphics g) {
    JTable.DropLocation loc = table.getDropLocation();

    if (loc == null) {
      return;
    }

    Color color = (Color) style.get(context, "Table.dropLineColor");
    Color shortColor = (Color) style.get(context, "Table.dropLineShortColor");

    if (color == null && shortColor == null) {
      return;
    }

    Rectangle rect;

    rect = getHDropLineRect(loc);
    if (rect != null) {
      int x = rect.x;
      int w = rect.width;

      if (color != null) {
        extendRect(rect, true);
        g.setColor(color);
        g.fillRect(rect.x, rect.y, rect.width, rect.height);
      }

      if (!loc.isInsertColumn() && shortColor != null) {
        g.setColor(shortColor);
        g.fillRect(x, rect.y, w, rect.height);
      }
    }

    rect = getVDropLineRect(loc);
    if (rect != null) {
      int y = rect.y;
      int h = rect.height;

      if (color != null) {
        extendRect(rect, false);
        g.setColor(color);
        g.fillRect(rect.x, rect.y, rect.width, rect.height);
      }

      if (!loc.isInsertRow() && shortColor != null) {
        g.setColor(shortColor);
        g.fillRect(rect.x, y, rect.width, h);
      }
    }
  }
  public Component getTableCellRendererComponentWithSubstance(
      JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

    TableUI tableUI = table.getUI();
    SubstanceTableUI ui = (SubstanceTableUI) tableUI;

    // Recompute the focus indication to prevent flicker - JTable
    // registers a listener on selection changes and repaints the
    // relevant cell before our listener (in TableUI) gets the
    // chance to start the fade sequence. The result is that the
    // first frame uses full opacity, and the next frame starts the
    // fade sequence. So, we use the UI delegate to compute the
    // focus indication.
    hasFocus = ui.isFocusedCell(row, column);

    TableCellId cellId = new TableCellId(row, column);

    StateTransitionTracker.ModelStateInfo modelStateInfo = ui.getModelStateInfo(cellId);
    ComponentState currState = ui.getCellState(cellId);
    // special case for drop location
    JTable.DropLocation dropLocation = table.getDropLocation();
    boolean isDropLocation =
        (dropLocation != null
            && !dropLocation.isInsertRow()
            && !dropLocation.isInsertColumn()
            && dropLocation.getRow() == row
            && dropLocation.getColumn() == column);

    if (!isDropLocation && (modelStateInfo != null)) {
      if (ui.hasRolloverAnimations() || ui.hasSelectionAnimations()) {
        Map<ComponentState, StateContributionInfo> activeStates =
            modelStateInfo.getStateContributionMap();
        SubstanceColorScheme colorScheme = getColorSchemeForState(table, ui, currState);
        if (currState.isDisabled() || (activeStates == null) || (activeStates.size() == 1)) {
          super.setForeground(new ColorUIResource(colorScheme.getForegroundColor()));
        } else {
          float aggrRed = 0;
          float aggrGreen = 0;
          float aggrBlue = 0;
          for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry :
              modelStateInfo.getStateContributionMap().entrySet()) {
            ComponentState activeState = activeEntry.getKey();
            SubstanceColorScheme scheme = getColorSchemeForState(table, ui, activeState);
            Color schemeFg = scheme.getForegroundColor();
            float contribution = activeEntry.getValue().getContribution();
            aggrRed += schemeFg.getRed() * contribution;
            aggrGreen += schemeFg.getGreen() * contribution;
            aggrBlue += schemeFg.getBlue() * contribution;
          }
          super.setForeground(
              new ColorUIResource(new Color((int) aggrRed, (int) aggrGreen, (int) aggrBlue)));
        }
      } else {
        SubstanceColorScheme scheme = getColorSchemeForState(table, ui, currState);
        super.setForeground(new ColorUIResource(scheme.getForegroundColor()));
      }
    } else {
      SubstanceColorScheme scheme = getColorSchemeForState(table, ui, currState);
      if (isDropLocation) {
        scheme =
            SubstanceColorSchemeUtilities.getColorScheme(
                table, ColorSchemeAssociationKind.TEXT_HIGHLIGHT, currState);
      }
      super.setForeground(new ColorUIResource(scheme.getForegroundColor()));
    }

    SubstanceStripingUtils.applyStripedBackground(table, row, this);

    this.setFont(table.getFont());

    TableCellId cellFocusId = new TableCellId(row, column);

    StateTransitionTracker focusStateTransitionTracker = ui.getStateTransitionTracker(cellFocusId);

    Insets regInsets = ui.getCellRendererInsets();
    if (hasFocus || (focusStateTransitionTracker != null)) {
      SubstanceTableCellBorder border = new SubstanceTableCellBorder(regInsets, ui, cellFocusId);

      // System.out.println("[" + row + ":" + column + "] hasFocus : "
      // + hasFocus + ", focusState : " + focusState);
      if (focusStateTransitionTracker != null) {
        border.setAlpha(focusStateTransitionTracker.getFocusStrength(hasFocus));
      }

      // special case for tables with no grids
      if (!table.getShowHorizontalLines() && !table.getShowVerticalLines()) {
        this.setBorder(
            new CompoundBorder(
                new EmptyBorder(table.getRowMargin() / 2, 0, table.getRowMargin() / 2, 0), border));
      } else {
        this.setBorder(border);
      }
    } else {
      this.setBorder(
          new EmptyBorder(regInsets.top, regInsets.left, regInsets.bottom, regInsets.right));
    }

    setValue(Math.min(100, getBarStatus(value)));
    setString(getDescription(value));
    this.setOpaque(false);
    this.setEnabled(table.isEnabled());
    return this;
  }