public void keyPressed(KeyEvent keyEvent) {
      AppLogger.finest(
          "keyModifiers=" + keyEvent.getModifiers() + " keyCode=" + keyEvent.getKeyCode());

      int keyCode = keyEvent.getKeyCode();
      if (keyCode == KeyEvent.VK_SHIFT
          || keyCode == KeyEvent.VK_CONTROL
          || keyCode == KeyEvent.VK_ALT
          || keyCode == KeyEvent.VK_META) return;

      KeyStroke pressedKeyStroke = KeyStroke.getKeyStrokeForEvent(keyEvent);

      if (pressedKeyStroke.equals(lastKeyStroke)) {
        TableCellEditor activeCellEditor = getCellEditor();
        if (activeCellEditor != null) activeCellEditor.stopCellEditing();
      } else {
        String actionId;
        if ((actionId = data.contains(pressedKeyStroke)) != null) {
          String errorMessage =
              "The shortcut ["
                  + KeyStrokeUtils.getKeyStrokeDisplayableRepresentation(pressedKeyStroke)
                  + "] is already assigned to '"
                  + ActionProperties.getActionDescription(actionId)
                  + "'";
          tooltipBar.showErrorMessage(errorMessage);
          createCancelEditingStateThread(getCellEditor());
        } else {
          lastKeyStroke = pressedKeyStroke;
          setText(KeyStrokeUtils.getKeyStrokeDisplayableRepresentation(lastKeyStroke));
        }
      }

      keyEvent.consume();
    }
    private void addMapping(String actionId, KeyStroke[] keyStrokes) throws IOException {
      XmlAttributes attributes = new XmlAttributes();
      attributes.add(ID_ATTRIBUTE, actionId);

      LOGGER.trace(
          "     Writing mapping of " + actionId + " to " + keyStrokes[0] + " and " + keyStrokes[1]);

      if (keyStrokes[0] != null)
        attributes.add(
            PRIMARY_KEYSTROKE_ATTRIBUTE, KeyStrokeUtils.getKeyStrokeRepresentation(keyStrokes[0]));

      if (keyStrokes[1] != null)
        attributes.add(
            ALTERNATE_KEYSTROKE_ATTRIBUTE,
            KeyStrokeUtils.getKeyStrokeRepresentation(keyStrokes[1]));

      writer.writeStandAloneElement(ACTION_ELEMENT, attributes);
    }
    public Component getTableCellRendererComponent(
        JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int rowIndex,
        int vColIndex) {
      DotBorderedCellLabel label;
      int columnId;

      columnId = convertColumnIndexToModel(vColIndex);
      label = cellLabels[columnId];

      // action's icon column: return ImageIcon instance
      if (columnId == ACTION_DESCRIPTION_COLUMN_INDEX) {
        Pair<ImageIcon, String> description = (Pair<ImageIcon, String>) value;
        label.setIcon(description.first);
        label.setText(description.second);

        // set cell's foreground color
        label.setForeground(
            ThemeCache.foregroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL][
                ThemeCache.PLAIN_FILE]);
      }
      // Any other column
      else {
        final KeyStroke key = (KeyStroke) value;
        String text = key == null ? "" : KeyStrokeUtils.getKeyStrokeDisplayableRepresentation(key);

        // If component's preferred width is bigger than column width then the component is not
        // entirely
        // visible so we set a tooltip text that will display the whole text when mouse is over the
        // component
        if (table.getColumnModel().getColumn(vColIndex).getWidth()
            < label.getPreferredSize().getWidth()) label.setToolTipText(text);
        // Have to set it to null otherwise the defaultRender sets the tooltip text to the last one
        // specified
        else label.setToolTipText(null);

        // Set label's text
        label.setText(text);
        // set cell's foreground color
        if (key != null) {
          boolean customized;
          switch (columnId) {
            case ACCELERATOR_COLUMN_INDEX:
              customized =
                  !key.equals(ActionProperties.getDefaultAccelerator(data.getActionId(rowIndex)));
              break;
            case ALTERNATE_ACCELERATOR_COLUMN_INDEX:
              customized =
                  !key.equals(
                      ActionProperties.getDefaultAlternativeAccelerator(
                          data.getActionId(rowIndex)));
              break;
            default:
              customized = false;
          }

          label.setForeground(
              ThemeCache.foregroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL][
                  customized ? ThemeCache.PLAIN_FILE : ThemeCache.HIDDEN_FILE]);
        }
      }

      // set outline for the focused cell
      label.setOutline(
          hasFocus ? ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.SELECTED] : null);
      // set cell's background color
      label.setBackground(
          ThemeCache.backgroundColors[ThemeCache.ACTIVE][
              rowIndex % 2 == 0 ? ThemeCache.NORMAL : ThemeCache.ALTERNATE]);

      return label;
    }