/** Sets current LAF. The method doesn't update component hierarchy. */
  @Override
  public void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo) {
    if (findLaf(lookAndFeelInfo.getClassName()) == null) {
      LOG.error("unknown LookAndFeel : " + lookAndFeelInfo);
      return;
    }
    // Set L&F
    if (IdeaLookAndFeelInfo.CLASS_NAME.equals(
        lookAndFeelInfo.getClassName())) { // that is IDEA default LAF
      IdeaLaf laf = new IdeaLaf();
      MetalLookAndFeel.setCurrentTheme(new IdeaBlueMetalTheme());
      try {
        UIManager.setLookAndFeel(laf);
      } catch (Exception e) {
        Messages.showMessageDialog(
            IdeBundle.message(
                "error.cannot.set.look.and.feel", lookAndFeelInfo.getName(), e.getMessage()),
            CommonBundle.getErrorTitle(),
            Messages.getErrorIcon());
        return;
      }
    } else if (DarculaLookAndFeelInfo.CLASS_NAME.equals(lookAndFeelInfo.getClassName())) {
      DarculaLaf laf = new DarculaLaf();
      try {
        UIManager.setLookAndFeel(laf);
        JBColor.setDark(true);
        IconLoader.setUseDarkIcons(true);
      } catch (Exception e) {
        Messages.showMessageDialog(
            IdeBundle.message(
                "error.cannot.set.look.and.feel", lookAndFeelInfo.getName(), e.getMessage()),
            CommonBundle.getErrorTitle(),
            Messages.getErrorIcon());
        return;
      }
    } else { // non default LAF
      try {
        LookAndFeel laf =
            ((LookAndFeel) Class.forName(lookAndFeelInfo.getClassName()).newInstance());
        if (laf instanceof MetalLookAndFeel) {
          MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme());
        }
        UIManager.setLookAndFeel(laf);
      } catch (Exception e) {
        Messages.showMessageDialog(
            IdeBundle.message(
                "error.cannot.set.look.and.feel", lookAndFeelInfo.getName(), e.getMessage()),
            CommonBundle.getErrorTitle(),
            Messages.getErrorIcon());
        return;
      }
    }
    myCurrentLaf =
        ObjectUtils.chooseNotNull(findLaf(lookAndFeelInfo.getClassName()), lookAndFeelInfo);

    checkLookAndFeel(lookAndFeelInfo, false);
  }
  /** Invoked via reflection. */
  LafManagerImpl() {
    myListenerList = new EventListenerList();

    List<UIManager.LookAndFeelInfo> lafList = ContainerUtil.newArrayList();

    if (SystemInfo.isMac) {
      if (Registry.is("ide.mac.yosemite.laf")
          && isIntelliJLafEnabled()
          && SystemInfo.isJavaVersionAtLeast("1.8")) {
        lafList.add(new UIManager.LookAndFeelInfo("Default", IntelliJLaf.class.getName()));
      } else {
        lafList.add(
            new UIManager.LookAndFeelInfo("Default", UIManager.getSystemLookAndFeelClassName()));
      }
    } else {
      if (isIntelliJLafEnabled()) {
        lafList.add(new IntelliJLookAndFeelInfo());
      } else {
        lafList.add(new IdeaLookAndFeelInfo());
      }
      for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
        String name = laf.getName();
        if (!"Metal".equalsIgnoreCase(name)
            && !"CDE/Motif".equalsIgnoreCase(name)
            && !"Nimbus".equalsIgnoreCase(name)
            && !"Windows Classic".equalsIgnoreCase(name)
            && !name.startsWith("JGoodies")) {
          lafList.add(laf);
        }
      }
    }

    lafList.add(new DarculaLookAndFeelInfo());

    myLaFs = lafList.toArray(new UIManager.LookAndFeelInfo[lafList.size()]);

    if (!SystemInfo.isMac) {
      // do not sort LaFs on mac - the order is determined as Default, Darcula.
      // when we leave only system LaFs on other OSes, the order also should be determined as
      // Default, Darcula

      Arrays.sort(
          myLaFs,
          new Comparator<UIManager.LookAndFeelInfo>() {
            @Override
            public int compare(UIManager.LookAndFeelInfo obj1, UIManager.LookAndFeelInfo obj2) {
              String name1 = obj1.getName();
              String name2 = obj2.getName();
              return name1.compareToIgnoreCase(name2);
            }
          });
    }

    myCurrentLaf = getDefaultLaf();
  }
  /**
   * 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();
  }
 /**
  * @return default LookAndFeelInfo for the running OS. For Win32 and Linux the method returns
  *     Alloy LAF or IDEA LAF if first not found, for Mac OS X it returns Aqua RubyMine uses Native
  *     L&F for linux as well
  */
 private UIManager.LookAndFeelInfo getDefaultLaf() {
   final String systemLafClassName = UIManager.getSystemLookAndFeelClassName();
   if (SystemInfo.isMac) {
     UIManager.LookAndFeelInfo laf = findLaf(systemLafClassName);
     LOG.assertTrue(laf != null);
     return laf;
   }
   if (PlatformUtils.isRubyMine() || PlatformUtils.isPyCharm()) {
     final String desktop = AccessController.doPrivileged(new GetPropertyAction("sun.desktop"));
     if ("gnome".equals(desktop)) {
       UIManager.LookAndFeelInfo laf = findLaf(systemLafClassName);
       if (laf != null) {
         return laf;
       }
       LOG.info("Could not find system look and feel: " + laf);
     }
   }
   // Default
   final String defaultLafName = StartupUtil.getDefaultLAF();
   if (defaultLafName != null) {
     UIManager.LookAndFeelInfo defaultLaf = findLaf(defaultLafName);
     if (defaultLaf != null) {
       return defaultLaf;
     }
   }
   UIManager.LookAndFeelInfo ideaLaf =
       findLaf(
           isIntelliJLafEnabled() ? IntelliJLaf.class.getName() : IdeaLookAndFeelInfo.CLASS_NAME);
   if (ideaLaf != null) {
     return ideaLaf;
   }
   throw new IllegalStateException("No default look&feel found");
 }
  @Nullable
  private static Icon getAquaMenuDisabledIcon() {
    final Icon arrowIcon = (Icon) UIManager.get("Menu.arrowIcon");
    if (arrowIcon != null) {
      return IconLoader.getDisabledIcon(arrowIcon);
    }

    return null;
  }
 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();
  }
  @Nullable
  private static Icon getAquaMenuInvertedIcon() {
    if (!UIUtil.isUnderAquaLookAndFeel()) return null;
    final Icon arrow = (Icon) UIManager.get("Menu.arrowIcon");
    if (arrow == null) return null;

    try {
      final Method method = ReflectionUtil.getMethod(arrow.getClass(), "getInvertedIcon");
      if (method != null) {
        return (Icon) method.invoke(arrow);
      }
      return null;
    } catch (InvocationTargetException e1) {
      return null;
    } catch (IllegalAccessException e1) {
      return null;
    }
  }