public FileColorsConfigurablePanel(@NotNull final FileColorManagerImpl manager) {
    setLayout(new BorderLayout());
    myManager = manager;

    final JPanel topPanel = new JPanel();
    topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));

    myEnabledCheckBox = new JCheckBox("Enable File Colors");
    myEnabledCheckBox.setMnemonic('F');
    topPanel.add(myEnabledCheckBox);

    myTabsEnabledCheckBox = new JCheckBox("Use in Editor Tabs");
    myTabsEnabledCheckBox.setMnemonic('T');
    topPanel.add(myTabsEnabledCheckBox);

    myProjectViewEnabledCheckBox = new JCheckBox("Use in Project View");
    myProjectViewEnabledCheckBox.setMnemonic('P');
    topPanel.add(myProjectViewEnabledCheckBox);

    topPanel.add(Box.createHorizontalGlue());

    add(topPanel, BorderLayout.NORTH);

    final JPanel mainPanel = new JPanel(new GridLayout(2, 1));
    mainPanel.setPreferredSize(JBUI.size(300, 500));
    mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0));

    final List<FileColorConfiguration> localConfigurations =
        manager.getApplicationLevelConfigurations();
    myLocalTable =
        new FileColorSettingsTable(manager, localConfigurations) {
          @Override
          protected void apply(@NotNull List<FileColorConfiguration> configurations) {
            final List<FileColorConfiguration> copied = new ArrayList<FileColorConfiguration>();
            try {
              for (final FileColorConfiguration configuration : configurations) {
                copied.add(configuration.clone());
              }
            } catch (CloneNotSupportedException e) { //
            }
            manager.getModel().setConfigurations(copied, false);
          }
        };

    final JPanel panel =
        ToolbarDecorator.createDecorator(myLocalTable)
            .addExtraAction(
                new AnActionButton("Share", AllIcons.Actions.Share) {
                  @Override
                  public void actionPerformed(AnActionEvent e) {
                    share();
                  }

                  @Override
                  public boolean isEnabled() {
                    return super.isEnabled() && myLocalTable.getSelectedRow() != -1;
                  }
                })
            .createPanel();
    final JPanel localPanel = new JPanel(new BorderLayout());
    localPanel.setBorder(IdeBorderFactory.createTitledBorder("Local colors", false));
    localPanel.add(panel, BorderLayout.CENTER);
    mainPanel.add(localPanel);

    mySharedTable =
        new FileColorSettingsTable(manager, manager.getProjectLevelConfigurations()) {
          @Override
          protected void apply(@NotNull List<FileColorConfiguration> configurations) {
            final List<FileColorConfiguration> copied = new ArrayList<FileColorConfiguration>();
            for (final FileColorConfiguration configuration : configurations) {
              try {
                copied.add(configuration.clone());
              } catch (CloneNotSupportedException e) {
                assert false : "Should not happen!";
              }
            }
            manager.getModel().setConfigurations(copied, true);
          }
        };

    final JPanel sharedPanel = new JPanel(new BorderLayout());
    sharedPanel.setBorder(IdeBorderFactory.createTitledBorder("Shared colors", false));
    final JPanel shared =
        ToolbarDecorator.createDecorator(mySharedTable)
            .addExtraAction(
                new AnActionButton("Unshare", AllIcons.Actions.Unshare) {
                  @Override
                  public void actionPerformed(AnActionEvent e) {
                    unshare();
                  }

                  @Override
                  public boolean isEnabled() {
                    return super.isEnabled() && mySharedTable.getSelectedRow() != -1;
                  }
                })
            .createPanel();

    sharedPanel.add(shared, BorderLayout.CENTER);
    mainPanel.add(sharedPanel);
    add(mainPanel, BorderLayout.CENTER);

    final JPanel infoPanel = new JPanel(new BorderLayout());
    infoPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    infoPanel.add(
        new JLabel(
            "Scopes are processed from top to bottom with Local colors first.",
            MessageType.INFO.getDefaultIcon(),
            SwingConstants.LEFT));
    JButton editScopes = new JButton("Manage Scopes...");
    editScopes.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(@NotNull ActionEvent e) {
            EditScopesDialog.showDialog(myManager.getProject(), null, true);
          }
        });
    infoPanel.add(editScopes, BorderLayout.EAST);
    add(infoPanel, BorderLayout.SOUTH);

    myLocalTable.getEmptyText().setText("No local colors");
    mySharedTable.getEmptyText().setText("No shared colors");
  }
  protected FontOptions(@NotNull ColorAndFontOptions options, final String title) {
    setLayout(new MigLayout("ins 0, gap 5, flowx"));
    Insets borderInsets =
        new Insets(
            IdeBorderFactory.TITLED_BORDER_TOP_INSET,
            IdeBorderFactory.TITLED_BORDER_LEFT_INSET,
            0,
            IdeBorderFactory.TITLED_BORDER_RIGHT_INSET);
    setBorder(IdeBorderFactory.createTitledBorder(title, false, borderInsets));
    myOptions = options;
    add(myOnlyMonospacedCheckBox, "sgx b, sx 2");

    add(new JLabel(ApplicationBundle.message("primary.font")), "newline, ax right");
    add(myPrimaryCombo, "sgx b");
    add(new JLabel(ApplicationBundle.message("editbox.font.size")), "gapleft 20");
    add(myEditorFontSizeField);
    add(new JLabel(ApplicationBundle.message("editbox.line.spacing")), "gapleft 20");
    add(myLineSpacingField);

    add(
        new JLabel(
            ApplicationBundle.message("label.fallback.fonts.list.description"),
            MessageType.INFO.getDefaultIcon(),
            SwingConstants.LEFT),
        "newline, sx 5");
    add(myUseSecondaryFontCheckbox, "newline, ax right");
    add(mySecondaryCombo, "sgx b");
    JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
    myEnableLigaturesCheckbox.setBorder(null);
    panel.add(myEnableLigaturesCheckbox);
    myLigaturesInfoLinkLabel =
        new LinkLabel<Void>(
            ApplicationBundle.message("ligatures.more.info"),
            null,
            new LinkListener<Void>() {
              @Override
              public void linkSelected(LinkLabel aSource, Void aLinkData) {
                BrowserUtil.browse(
                    "https://confluence.jetbrains.com/display/IDEADEV/Support+for+Ligatures+in+Editor");
              }
            });
    myLigaturesInfoLinkLabel.setBorder(new EmptyBorder(0, 5, 0, 0));
    panel.add(myLigaturesInfoLinkLabel);
    add(panel, "newline, sx 2");

    myOnlyMonospacedCheckBox.setBorder(null);
    myUseSecondaryFontCheckbox.setBorder(null);
    mySecondaryCombo.setEnabled(false);

    myOnlyMonospacedCheckBox.setSelected(
        EditorColorsManager.getInstance().isUseOnlyMonospacedFonts());
    myOnlyMonospacedCheckBox.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            EditorColorsManager.getInstance()
                .setUseOnlyMonospacedFonts(myOnlyMonospacedCheckBox.isSelected());
            myPrimaryCombo.setMonospacedOnly(myOnlyMonospacedCheckBox.isSelected());
            mySecondaryCombo.setMonospacedOnly(myOnlyMonospacedCheckBox.isSelected());
          }
        });
    myPrimaryCombo.setMonospacedOnly(myOnlyMonospacedCheckBox.isSelected());
    myPrimaryCombo.setRenderer(RENDERER);

    mySecondaryCombo.setMonospacedOnly(myOnlyMonospacedCheckBox.isSelected());
    mySecondaryCombo.setRenderer(RENDERER);

    myUseSecondaryFontCheckbox.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            mySecondaryCombo.setEnabled(myUseSecondaryFontCheckbox.isSelected());
            syncFontFamilies();
          }
        });
    ItemListener itemListener =
        new ItemListener() {
          @Override
          public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
              syncFontFamilies();
            }
          }
        };
    myPrimaryCombo.addItemListener(itemListener);
    mySecondaryCombo.addItemListener(itemListener);

    ActionListener actionListener =
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            syncFontFamilies();
          }
        };
    myPrimaryCombo.addActionListener(actionListener);
    mySecondaryCombo.addActionListener(actionListener);

    myEditorFontSizeField
        .getDocument()
        .addDocumentListener(
            new DocumentAdapter() {
              @Override
              public void textChanged(DocumentEvent event) {
                if (myIsInSchemeChange || !SwingUtilities.isEventDispatchThread()) return;
                String selectedFont = myPrimaryCombo.getFontName();
                if (selectedFont != null) {
                  FontPreferences fontPreferences = getFontPreferences();
                  fontPreferences.register(selectedFont, getFontSizeFromField());
                }
                updateDescription(true);
              }
            });
    myEditorFontSizeField.addKeyListener(
        new KeyAdapter() {
          @Override
          public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() != KeyEvent.VK_UP && e.getKeyCode() != KeyEvent.VK_DOWN) return;
            boolean up = e.getKeyCode() == KeyEvent.VK_UP;
            try {
              int value = Integer.parseInt(myEditorFontSizeField.getText());
              value += (up ? 1 : -1);
              value =
                  Math.min(
                      OptionsConstants.MAX_EDITOR_FONT_SIZE,
                      Math.max(OptionsConstants.MIN_EDITOR_FONT_SIZE, value));
              myEditorFontSizeField.setText(String.valueOf(value));
            } catch (NumberFormatException ignored) {
            }
          }
        });

    myLineSpacingField
        .getDocument()
        .addDocumentListener(
            new DocumentAdapter() {
              @Override
              public void textChanged(DocumentEvent event) {
                if (myIsInSchemeChange) return;
                float lineSpacing = getLineSpacingFromField();
                if (getLineSpacing() != lineSpacing) {
                  setCurrentLineSpacing(lineSpacing);
                }
                updateDescription(true);
              }
            });
    myLineSpacingField.addKeyListener(
        new KeyAdapter() {
          @Override
          public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() != KeyEvent.VK_UP && e.getKeyCode() != KeyEvent.VK_DOWN) return;
            boolean up = e.getKeyCode() == KeyEvent.VK_UP;
            try {
              float value = Float.parseFloat(myLineSpacingField.getText());
              value += (up ? 1 : -1) * .1F;
              value =
                  Math.min(
                      OptionsConstants.MAX_EDITOR_LINE_SPACING,
                      Math.max(OptionsConstants.MIN_EDITOR_LINE_SPACING, value));
              myLineSpacingField.setText(String.format(Locale.ENGLISH, "%.1f", value));
            } catch (NumberFormatException ignored) {
            }
          }
        });
    myEnableLigaturesCheckbox.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            getFontPreferences().setUseLigatures(myEnableLigaturesCheckbox.isSelected());
          }
        });
  }