private static void patchGtkDefaults(UIDefaults defaults) {
    if (!UIUtil.isUnderGTKLookAndFeel()) return;

    Map<String, Icon> map =
        ContainerUtil.newHashMap(
            Arrays.asList(
                "OptionPane.errorIcon",
                "OptionPane.informationIcon",
                "OptionPane.warningIcon",
                "OptionPane.questionIcon"),
            Arrays.asList(
                AllIcons.General.ErrorDialog,
                AllIcons.General.InformationDialog,
                AllIcons.General.WarningDialog,
                AllIcons.General.QuestionDialog));
    // GTK+ L&F keeps icons hidden in style
    SynthStyle style = SynthLookAndFeel.getStyle(new JOptionPane(""), Region.DESKTOP_ICON);
    for (String key : map.keySet()) {
      if (defaults.get(key) != null) continue;

      Object icon = style == null ? null : style.get(null, key);
      defaults.put(key, icon instanceof Icon ? icon : map.get(key));
    }

    Color fg = defaults.getColor("Label.foreground");
    Color bg = defaults.getColor("Label.background");
    if (fg != null && bg != null) {
      defaults.put("Label.disabledForeground", UIUtil.mix(fg, bg, 0.5));
    }
  }
  /**
   * Updates LAF of all windows. The method also updates font of components as it's configured in
   * <code>UISettings</code>.
   */
  @Override
  public void updateUI() {
    final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();

    fixPopupWeight();

    fixGtkPopupStyle();

    fixTreeWideSelection(uiDefaults);

    fixMenuIssues(uiDefaults);

    if (UIUtil.isUnderAquaLookAndFeel()) {
      uiDefaults.put("Panel.opaque", Boolean.TRUE);
    } else if (UIUtil.isWinLafOnVista()) {
      uiDefaults.put("ComboBox.border", null);
    }

    initInputMapDefaults(uiDefaults);

    uiDefaults.put("Button.defaultButtonFollowsFocus", Boolean.FALSE);

    patchFileChooserStrings(uiDefaults);

    patchLafFonts(uiDefaults);

    patchOptionPaneIcons(uiDefaults);

    fixSeparatorColor(uiDefaults);

    for (Frame frame : Frame.getFrames()) {
      updateUI(frame);
    }
    fireLookAndFeelChanged();
  }
 private static void fixTreeWideSelection(UIDefaults uiDefaults) {
   if (UIUtil.isUnderAlloyIDEALookAndFeel() || UIUtil.isUnderJGoodiesLookAndFeel()) {
     final Color bg = new ColorUIResource(56, 117, 215);
     final Color fg = new ColorUIResource(255, 255, 255);
     uiDefaults.put("info", bg);
     uiDefaults.put("textHighlight", bg);
     for (String key : ourAlloyComponentsToPatchSelection) {
       uiDefaults.put(key + ".selectionBackground", bg);
       uiDefaults.put(key + ".selectionForeground", fg);
     }
   }
 }
 private static void fixMenuIssues(UIDefaults uiDefaults) {
   if (UIUtil.isUnderAquaLookAndFeel()) {
     // update ui for popup menu to get round corners
     uiDefaults.put("PopupMenuUI", MacPopupMenuUI.class.getCanonicalName());
     uiDefaults.put("Menu.invertedArrowIcon", getAquaMenuInvertedIcon());
     uiDefaults.put("Menu.disabledArrowIcon", getAquaMenuDisabledIcon());
   } else if (UIUtil.isUnderJGoodiesLookAndFeel()) {
     uiDefaults.put("Menu.opaque", true);
     uiDefaults.put("MenuItem.opaque", true);
   }
   uiDefaults.put("MenuItem.background", UIManager.getColor("Menu.background"));
 }
  /**
   * Updates LAF of all windows. The method also updates font of components as it's configured in
   * <code>UISettings</code>.
   */
  @Override
  public void updateUI() {
    final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();

    fixPopupWeight();

    fixGtkPopupStyle();

    fixTreeWideSelection(uiDefaults);

    fixMenuIssues(uiDefaults);

    if (UIUtil.isUnderAquaLookAndFeel()) {
      uiDefaults.put("Panel.opaque", Boolean.TRUE);
    } else if (UIUtil.isWinLafOnVista()) {
      uiDefaults.put("ComboBox.border", null);
    }

    initInputMapDefaults(uiDefaults);

    uiDefaults.put("Button.defaultButtonFollowsFocus", Boolean.FALSE);

    patchFileChooserStrings(uiDefaults);

    patchLafFonts(uiDefaults);

    patchHiDPI(uiDefaults);

    patchGtkDefaults(uiDefaults);

    fixSeparatorColor(uiDefaults);

    updateToolWindows();

    for (Frame frame : Frame.getFrames()) {
      // OSX/Aqua fix: Some image caching components like ToolWindowHeader use
      // com.apple.laf.AquaNativeResources$CColorPaintUIResource
      // a Java wrapper for ObjC MagicBackgroundColor class (Java RGB values ignored).
      // MagicBackgroundColor always reports current Frame background.
      // So we need to set frames background to exact and correct value.
      if (SystemInfo.isMac) {
        //noinspection UseJBColor
        frame.setBackground(new Color(UIUtil.getPanelBackground().getRGB()));
      }

      updateUI(frame);
    }
    fireLookAndFeelChanged();
  }
  @SuppressWarnings({"HardCodedStringLiteral"})
  static void initFontDefaults(UIDefaults defaults, int fontSize, FontUIResource uiFont) {
    defaults.put("Tree.ancestorInputMap", null);
    FontUIResource textFont = new FontUIResource("Serif", Font.PLAIN, fontSize);
    FontUIResource monoFont = new FontUIResource("Monospaced", Font.PLAIN, fontSize);

    for (String fontResource : ourPatchableFontResources) {
      defaults.put(fontResource, uiFont);
    }

    defaults.put("PasswordField.font", monoFont);
    defaults.put("TextArea.font", monoFont);
    defaults.put("TextPane.font", textFont);
    defaults.put("EditorPane.font", textFont);
  }
  private static void patchHiDPI(UIDefaults defaults) {
    if (!JBUI.isHiDPI()) return;

    List<String> myIntKeys = Arrays.asList("Tree.leftChildIndent", "Tree.rightChildIndent");
    List<String> patched = new ArrayList<String>();
    for (Map.Entry<Object, Object> entry : defaults.entrySet()) {
      Object value = entry.getValue();
      String key = entry.getKey().toString();
      if (value instanceof DimensionUIResource) {
        entry.setValue(JBUI.size((DimensionUIResource) value).asUIResource());
      } else if (value instanceof InsetsUIResource) {
        entry.setValue(JBUI.insets(((InsetsUIResource) value)).asUIResource());
      } else if (value instanceof Integer) {
        if (key.endsWith(".maxGutterIconWidth") || myIntKeys.contains(key)) {
          if (!"true".equals(defaults.get(key + ".hidpi.patched"))) {
            entry.setValue(Integer.valueOf(JBUI.scale((Integer) value)));
            patched.add(key);
          }
        }
      }
    }
    for (String key : patched) {
      defaults.put(key + ".hidpi.patched", "true");
    }
  }
 private static void patchFileChooserStrings(final UIDefaults defaults) {
   if (!defaults.containsKey(ourFileChooserTextKeys[0])) {
     // Alloy L&F does not define strings for names of context menu actions, so we have to patch
     // them in here
     for (String key : ourFileChooserTextKeys) {
       defaults.put(key, IdeBundle.message(key));
     }
   }
 }
 private void restoreOriginalFontDefaults(UIDefaults defaults) {
   UIManager.LookAndFeelInfo lf = getCurrentLookAndFeel();
   HashMap<String, Object> lfDefaults = myStoredDefaults.get(lf);
   if (lfDefaults != null) {
     for (String resource : ourPatchableFontResources) {
       defaults.put(resource, lfDefaults.get(resource));
     }
   }
 }
 private static void patchOptionPaneIcons(final UIDefaults defaults) {
   if (UIUtil.isUnderGTKLookAndFeel() && defaults.get(ourOptionPaneIconKeys[0]) == null) {
     // GTK+ L&F keeps icons hidden in style
     final SynthStyle style = SynthLookAndFeel.getStyle(new JOptionPane(""), Region.DESKTOP_ICON);
     if (style != null) {
       for (final String key : ourOptionPaneIconKeys) {
         final Object icon = style.get(null, key);
         if (icon != null) defaults.put(key, icon);
       }
     }
   }
 }
 private static void fixSeparatorColor(UIDefaults uiDefaults) {
   if (UIUtil.isUnderAquaLookAndFeel()) {
     uiDefaults.put("Separator.background", UIUtil.AQUA_SEPARATOR_BACKGROUND_COLOR);
     uiDefaults.put("Separator.foreground", UIUtil.AQUA_SEPARATOR_FOREGROUND_COLOR);
   }
 }