@Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    if (myCurrentWindow == null || myCurrentWindow.getFiles().length == 0) {
      g.setColor(UIUtil.isUnderDarcula() ? UIUtil.getBorderColor() : new Color(0, 0, 0, 50));
      g.drawLine(0, 0, getWidth(), 0);
    }

    if (showEmptyText()) {
      UIUtil.applyRenderingHints(g);
      g.setColor(new JBColor(Gray._100, Gray._160));
      g.setFont(UIUtil.getLabelFont().deriveFont(UIUtil.isUnderDarcula() ? 24f : 18f));

      final UIUtil.TextPainter painter =
          new UIUtil.TextPainter().withShadow(true).withLineSpacing(1.4f);
      painter.appendLine("No files are open").underlined(new JBColor(Gray._150, Gray._100));

      if (!isProjectViewVisible()) {
        painter
            .appendLine(
                "Open Project View with "
                    + KeymapUtil.getShortcutText(
                        new KeyboardShortcut(
                            KeyStroke.getKeyStroke((SystemInfo.isMac ? "meta" : "alt") + " 1"),
                            null)))
            .smaller()
            .withBullet();
      }

      painter
          .appendLine("Open a file by name with " + getActionShortcutText("GotoFile"))
          .smaller()
          .withBullet()
          .appendLine(
              "Open Recent files with " + getActionShortcutText(IdeActions.ACTION_RECENT_FILES))
          .smaller()
          .withBullet()
          .appendLine("Open Navigation Bar with " + getActionShortcutText("ShowNavBar"))
          .smaller()
          .withBullet()
          .appendLine("Drag'n'Drop file(s) here from " + ShowFilePathAction.getFileManagerName())
          .smaller()
          .withBullet()
          .draw(
              g,
              new PairFunction<Integer, Integer, Pair<Integer, Integer>>() {
                @Override
                public Pair<Integer, Integer> fun(Integer width, Integer height) {
                  final Dimension s = getSize();
                  return Pair.create((s.width - width) / 2, (s.height - height) / 2);
                }
              });
    }
  }
  @Override
  protected void paintComponent(final Graphics g) {
    String s = getText();
    final Rectangle bounds = getBounds();
    if (UIUtil.isUnderDarcula()) {
      g.setColor(UIUtil.getPanelBackground());
      g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
    }
    if (s == null) return;
    final Insets insets = getInsets();

    final Graphics2D g2 = (Graphics2D) g;
    g2.setFont(getFont());

    UIUtil.applyRenderingHints(g2);

    final FontMetrics fm = g2.getFontMetrics();
    final int sWidth = fm.stringWidth(s);

    int x = insets.left;
    if (myAlignment == Component.CENTER_ALIGNMENT || myAlignment == Component.RIGHT_ALIGNMENT) {
      x =
          myAlignment == Component.CENTER_ALIGNMENT
              ? (bounds.width - sWidth) / 2
              : bounds.width - insets.right - sWidth;
    }

    final Rectangle textR = new Rectangle();
    final Rectangle iconR = new Rectangle();
    final Rectangle viewR = new Rectangle(bounds);
    textR.x = textR.y = textR.width = textR.height = 0;

    viewR.width -= insets.left;
    viewR.width -= insets.right;

    final int maxWidth = bounds.width - insets.left - insets.right;
    if (sWidth > maxWidth) {
      s = truncateText(s, bounds, fm, textR, iconR, maxWidth);
    }

    final int y = UIUtil.getStringY(s, bounds, g2);
    if (SystemInfo.isMac && !UIUtil.isUnderDarcula() && myDecorate) {
      g2.setColor(myCustomColor == null ? Gray._215 : myCustomColor);
      g2.drawString(s, x, y + 1);
    }

    g2.setColor(myCustomColor == null ? getForeground() : myCustomColor);
    g2.drawString(s, x, y);
  }
  public static List<Pair<String, Integer>> getFileNames(@NotNull String file) {
    final boolean dark = UIUtil.isUnderDarcula();
    final boolean retina = UIUtil.isRetina();
    if (retina || dark) {
      List<Pair<String, Integer>> answer = new ArrayList<Pair<String, Integer>>(4);

      final String name = FileUtil.getNameWithoutExtension(file);
      final String ext = FileUtilRt.getExtension(file);
      if (dark && retina) {
        answer.add(Pair.create(name + "@2x_dark." + ext, 2));
      }

      if (dark) {
        answer.add(Pair.create(name + "_dark." + ext, 1));
      }

      if (retina) {
        answer.add(Pair.create(name + "@2x." + ext, 2));
      }

      answer.add(Pair.create(file, 1));

      return answer;
    }

    return Collections.singletonList(Pair.create(file, 1));
  }
 @NotNull
 public static JEditorPane createTipBrowser() {
   JEditorPane browser = new JEditorPane();
   browser.setEditable(false);
   browser.setBackground(UIUtil.getTextFieldBackground());
   browser.addHyperlinkListener(
       new HyperlinkListener() {
         public void hyperlinkUpdate(HyperlinkEvent e) {
           if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
             BrowserUtil.browse(e.getURL());
           }
         }
       });
   URL resource =
       ResourceUtil.getResource(
           TipUIUtil.class,
           "/tips/css/",
           UIUtil.isUnderDarcula() ? "tips_darcula.css" : "tips.css");
   final StyleSheet styleSheet = UIUtil.loadStyleSheet(resource);
   HTMLEditorKit kit =
       new HTMLEditorKit() {
         @Override
         public StyleSheet getStyleSheet() {
           return styleSheet != null ? styleSheet : super.getStyleSheet();
         }
       };
   browser.setEditorKit(kit);
   return browser;
 }
    @Override
    public Icon scale(float scaleFactor) {
      if (scaleFactor == 1f) {
        return this;
      }
      if (scaledIcons == null) {
        scaledIcons = new HashMap<Float, Icon>(1);
      }

      Icon result = scaledIcons.get(scaleFactor);
      if (result != null) {
        return result;
      }

      final Image image =
          ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), scaleFactor >= 1.5f, filter);
      if (image != null) {
        int width = (int) (getIconWidth() * scaleFactor);
        int height = (int) (getIconHeight() * scaleFactor);
        final BufferedImage resizedImage =
            Scalr.resize(
                ImageUtil.toBufferedImage(image), Scalr.Method.ULTRA_QUALITY, width, height);
        result = getIcon(resizedImage);
        scaledIcons.put(scaleFactor, result);
        return result;
      }

      return this;
    }
 private JTextField createColorField(boolean hex) {
   final NumberDocument doc = new NumberDocument(hex);
   int lafFix = UIUtil.isUnderWindowsLookAndFeel() || UIUtil.isUnderDarcula() ? 1 : 0;
   UIManager.LookAndFeelInfo info = LafManager.getInstance().getCurrentLookAndFeel();
   if (info != null
       && (info.getName().startsWith("IDEA") || info.getName().equals("Windows Classic")))
     lafFix = 1;
   final JTextField field;
   if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) {
     field = new JTextField("");
     field.setDocument(doc);
     field.setPreferredSize(new Dimension(hex ? 60 : 40, 26));
   } else {
     field = new JTextField(doc, "", (hex ? 5 : 2) + lafFix);
     field.setSize(50, -1);
   }
   doc.setSource(field);
   field.getDocument().addDocumentListener(this);
   field.addFocusListener(
       new FocusAdapter() {
         @Override
         public void focusGained(final FocusEvent e) {
           field.selectAll();
         }
       });
   return field;
 }
 @Override
 protected void paintComponent(@NotNull Graphics g) {
   super.paintComponent(g);
   if (UIUtil.isUnderDarcula()) {
     g.setColor(UIUtil.getControlColor().brighter());
     g.fillRect(0, 0, getWidth(), getHeight());
   }
 }
Example #8
0
 @Override
 protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   if (UIUtil.isUnderDarcula() && false) { // todo[kb] fix DarculaTextBorder
     g.setColor(myTextField.getBackground());
     g.fillRect(2, 3, getWidth(), getHeight() - 5);
   }
 }
 @NotNull
 public static Color getLabelColor(@NotNull Color color) {
   if (UIUtil.isUnderDarcula()) {
     color = ColorUtil.darker(color, 6);
   } else {
     color = ColorUtil.brighter(color, 6);
   }
   return ColorUtil.desaturate(color, 3);
 }
 @Override
 protected void paintComponent(Graphics g) {
   if (showEmptyText()) {
     Graphics2D gg = IdeBackgroundUtil.withFrameBackground(g, this);
     super.paintComponent(gg);
     g.setColor(UIUtil.isUnderDarcula() ? UIUtil.getBorderColor() : new Color(0, 0, 0, 50));
     g.drawLine(0, 0, getWidth(), 0);
   }
 }
 private void updateBackground() {
   if (UIUtil.isUnderDarcula()) {
     setBackgroundImage(IconLoader.getIcon("/frame_background.png"));
     String icon = ApplicationInfoEx.getInstanceEx().getEditorBackgroundImageUrl();
     if (icon != null) setCenterImage(IconLoader.getIcon(icon));
   } else {
     setBackgroundImage(null);
     setCenterImage(null);
   }
 }
 @Override
 public JComponent createCustomComponent(Presentation presentation) {
   JPanel panel = new JPanel();
   JLabel filterCaption = new JLabel("Filter:");
   filterCaption.setForeground(
       UIUtil.isUnderDarcula() ? UIUtil.getLabelForeground() : UIUtil.getInactiveTextColor());
   panel.add(filterCaption);
   panel.add(createSearchField());
   return panel;
 }
 @Nullable
 public static Image loadFromResource(@NonNls @NotNull String path, @NotNull Class aClass) {
   return ImageDescList.create(
           path,
           aClass,
           UIUtil.isUnderDarcula(),
           UIUtil.isRetina() || JBUI.scale(1.0f) >= 1.5f,
           true)
       .load(ImageConverterChain.create().withRetina());
 }
 @Override
 public void paint(Graphics g) {
   UIUtil.paintWithRetina(
       getSize(),
       g,
       UIUtil.isUnderDarcula(),
       new Consumer<Graphics2D>() {
         @Override
         public void consume(Graphics2D graphics) {
           doPaint(graphics);
         }
       });
 }
  @Override
  public void initComponent() {
    if (myCurrentLaf != null) {
      final UIManager.LookAndFeelInfo laf = findLaf(myCurrentLaf.getClassName());
      if (laf != null) {
        boolean needUninstall = UIUtil.isUnderDarcula();
        setCurrentLookAndFeel(laf); // setup default LAF or one specified by readExternal.
        if (WelcomeWizardUtil.getWizardLAF() != null) {
          if (UIUtil.isUnderDarcula()) {
            DarculaInstaller.install();
          } else if (needUninstall) {
            DarculaInstaller.uninstall();
          }
        }
      }
    }

    updateUI();

    if (SystemInfo.isXWindow) {
      myThemeChangeListener =
          new PropertyChangeListener() {
            @Override
            public void propertyChange(final PropertyChangeEvent evt) {
              //noinspection SSBasedInspection
              SwingUtilities.invokeLater(
                  new Runnable() {
                    @Override
                    public void run() {
                      fixGtkPopupStyle();
                      patchGtkDefaults(UIManager.getLookAndFeelDefaults());
                    }
                  });
            }
          };
      Toolkit.getDefaultToolkit()
          .addPropertyChangeListener(GNOME_THEME_PROPERTY_NAME, myThemeChangeListener);
    }
  }
 @Override
 public void paintBorder(
     final Component c,
     final Graphics g,
     final int x,
     final int y,
     final int width,
     final int height) {
   if (UIUtil.isUnderDarcula()) {
     g.setColor(Gray._40);
     doPaintBorder(c, g, x, y, width, height);
   } else {
     g.setColor(UIUtil.getPanelBackground());
     doPaintBorder(c, g, x, y, width, height);
     g.setColor(Gray._155);
     doPaintBorder(c, g, x, y, width, height);
   }
 }
  @Override
  protected void paintChildren(Graphics g) {
    super.paintChildren(g);
    boolean dark = UIUtil.isUnderDarcula();
    int off = dark ? 6 : 0;
    AllIcons.General.ArrowDown.paintIcon(this, g, myMoreRec.x - off, myMoreRec.y);
    if (dark) return;

    final Insets insets = getInsets();
    int y1 = myMoreRec.y - 2;
    int y2 = getHeight() - insets.bottom - 2;

    if (y1 < getInsets().top) {
      y1 = insets.top;
    }

    final int x = myMoreRec.x - 4;
    UIUtil.drawDottedLine(((Graphics2D) g), x, y1, x, y2, null, Color.darkGray);
  }
  private static void updateImages(StringBuffer text, ClassLoader tipLoader) {
    final boolean dark = UIUtil.isUnderDarcula();
    final boolean retina = UIUtil.isRetina();
    //    if (!dark && !retina) {
    //      return;
    //    }

    String suffix = "";
    if (retina) suffix += "@2x";
    if (dark) suffix += "_dark";
    int index = text.indexOf("<img", 0);
    while (index != -1) {
      final int end = text.indexOf(">", index + 1);
      if (end == -1) return;
      final String img = text.substring(index, end + 1).replace('\r', ' ').replace('\n', ' ');
      final int srcIndex = img.indexOf("src=");
      final int endIndex = img.indexOf(".png", srcIndex);
      if (endIndex != -1) {
        String path = img.substring(srcIndex + 5, endIndex);
        if (!path.endsWith("_dark") && !path.endsWith("@2x")) {
          path += suffix + ".png";
          URL url = ResourceUtil.getResource(tipLoader, "/tips/", path);
          if (url != null) {
            String newImgTag = "<img src=\"" + path + "\" ";
            if (retina) {
              try {
                final BufferedImage image = ImageIO.read(url.openStream());
                final int w = image.getWidth() / 2;
                final int h = image.getHeight() / 2;
                newImgTag += "width=\"" + w + "\" height=\"" + h + "\"";
              } catch (Exception ignore) {
                newImgTag += "width=\"400\" height=\"200\"";
              }
            }
            newImgTag += "/>";
            text.replace(index, end + 1, newImgTag);
          }
        }
      }
      index = text.indexOf("<img", index + 1);
    }
  }
  @Override
  public void paint(Graphics2D g, int x, int y, int width, int height, Integer object) {
    g = (Graphics2D) g.create(x, y, width, height);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f));
    g.setStroke(BASIC_STROKE);

    boolean dark = UIUtil.isUnderDarcula();
    int offset = object != null ? object + 11 : 11;
    Color start = getColor(dark ? 95 + offset : 251 - offset);
    Color stop = getColor(dark ? 80 + offset : 215 - offset);

    Paint paint;
    if (Adjustable.VERTICAL == myScrollBar.getOrientation()) {
      x = 2;
      y = 1;
      width -= 3;
      height -= 2;
      if (myPainter instanceof ExtraErrorStripePainter) {
        ExtraErrorStripePainter extra = (ExtraErrorStripePainter) myPainter;
        int gap = extra.getMinimalThickness() - 1;
        x += gap;
        width -= gap;
      }
      paint = UIUtil.getGradientPaint(x, 0, start, x + width, 0, stop);
    } else {
      x = 1;
      y = 2;
      width -= 2;
      height -= 3;
      paint = UIUtil.getGradientPaint(0, y, start, 0, y + height, stop);
    }
    int arc = JBUI.scale(3);
    g.setPaint(paint);
    g.fillRoundRect(x + 1, y + 1, width - 2, height - 2, arc, arc);
    g.setColor(getColor(dark ? 85 : 201));
    g.drawRoundRect(x, y, width - 1, height - 1, arc, arc);
    g.dispose();
  }
  public CommitLegendPanel(InfoCalculator infoCalculator) {
    myInfoCalculator = infoCalculator;
    final Color background = UIUtil.getListBackground();
    myModifiedPanel.setBackground(background);
    myNewPanel.setBackground(background);
    myDeletedPanel.setBackground(background);
    if (UIUtil.isUnderDarcula()) {
      final Color color = UIUtil.getSeparatorColor();
      final TitledBorder border = new TitledBorder(new LineBorder(color, 1));
      myModifiedPanel.setBorder(border);
      myNewPanel.setBorder(border);
      myDeletedPanel.setBorder(border);
    }

    myModifiedLabel.setForeground(FileStatus.MODIFIED.getColor());
    myNewLabel.setForeground(FileStatus.ADDED.getColor());
    myDeletedLabel.setForeground(FileStatus.DELETED.getColor());

    boldLabel(myModifiedLabel, true);
    boldLabel(myNewLabel, true);
    boldLabel(myDeletedLabel, true);
  }
    private String setup(
        @NotNull String text,
        @NotNull Map<TextRange, ParameterInfoUIContextEx.Flag> flagsMap,
        @NotNull Color background) {
      myLabel.setBackground(background);
      setBackground(background);

      myLabel.setForeground(JBColor.foreground());

      if (flagsMap.isEmpty()) {
        myLabel.setText(XmlStringUtil.wrapInHtml(text));
      } else {
        String labelText = buildLabelText(text, flagsMap);
        myLabel.setText(labelText);
      }

      // IDEA-95904 Darcula parameter info pop-up colors hard to read
      if (UIUtil.isUnderDarcula()) {
        myLabel.setText(myLabel.getText().replace("<b>", "<b color=ffC800>"));
      }
      return myLabel.getText();
    }
  @Override
  public void apply() throws ConfigurationException {
    if (myApplyCompleted) {
      return;
    }
    try {
      EditorColorsManager myColorsManager = EditorColorsManager.getInstance();

      myColorsManager.removeAllSchemes();
      for (MyColorScheme scheme : mySchemes.values()) {
        if (!scheme.isDefault()) {
          scheme.apply();
          myColorsManager.addColorsScheme(scheme.getOriginalScheme());
        }
      }

      EditorColorsScheme originalScheme = mySelectedScheme.getOriginalScheme();
      myColorsManager.setGlobalScheme(originalScheme);
      if (originalScheme != null
          && DarculaLaf.NAME.equals(originalScheme.getName())
          && !UIUtil.isUnderDarcula()) {
        int ok =
            Messages.showYesNoDialog(
                "Darcula color scheme has been set for editors. Would you like to set Darcula as default Look and Feel?",
                "Darcula Look and Feel",
                Messages.getQuestionIcon());
        if (ok == Messages.YES) {
          LafManager.getInstance().setCurrentLookAndFeel(new DarculaLookAndFeelInfo());
          DarculaInstaller.install();
        }
      }
      applyChangesToEditors();

      reset();
    } finally {
      myApplyCompleted = true;
    }
  }
  @Nullable
  public static Image loadFromUrl(
      @NotNull URL url, boolean allowFloatScaling, ImageFilter[] filters) {
    final float scaleFactor = calcScaleFactor(allowFloatScaling);

    // We can't check all 3rd party plugins and convince the authors to add @2x icons.
    // (scaleFactor > 1.0) != isRetina() => we should scale images manually.
    // Note we never scale images on Retina displays because scaling is handled by the system.
    final boolean scaleImages = (scaleFactor > 1.0f) && !UIUtil.isRetina();

    // For any scale factor > 1.0, always prefer retina images, because downscaling
    // retina images provides a better result than upscaling non-retina images.
    final boolean loadRetinaImages = UIUtil.isRetina() || scaleImages;

    return ImageDescList.create(
            url.toString(), null, UIUtil.isUnderDarcula(), loadRetinaImages, allowFloatScaling)
        .load(
            ImageConverterChain.create()
                .withFilter(filters)
                .withRetina()
                .with(
                    new ImageConverter() {
                      public Image convert(Image source, ImageDesc desc) {
                        if (source != null && scaleImages && desc.type != ImageDesc.Type.SVG) {
                          if (desc.path.contains("@2x"))
                            return scaleImage(
                                source,
                                scaleFactor
                                    / 2.0f); // divide by 2.0 as Retina images are 2x the
                                             // resolution.
                          else return scaleImage(source, scaleFactor);
                        }
                        return source;
                      }
                    }));
  }
 @Override
 protected final boolean isWideSelection() {
   return UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF();
 }
 private static boolean isUsingDarculaUIFlavor() {
   return UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF();
 }
  protected JComponent createSouthPanel() {
    JPanel panel = new JPanel(new BorderLayout());
    panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));

    JPanel buttonPanel = new JPanel();

    if (SystemInfo.isMac) {
      panel.add(buttonPanel, BorderLayout.EAST);
      buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));

      if (!UIUtil.isUnderDarcula()) {
        myHelpButton.putClientProperty("JButton.buttonType", "help");
      }
      if (UIUtil.isUnderAquaLookAndFeel()) {
        myHelpButton.setText("");
      }

      JPanel leftPanel = new JPanel();
      if (ApplicationInfo.contextHelpAvailable()) {
        leftPanel.add(myHelpButton);
      }
      leftPanel.add(myCancelButton);
      panel.add(leftPanel, BorderLayout.WEST);

      if (mySteps.size() > 1) {
        buttonPanel.add(Box.createHorizontalStrut(5));
        buttonPanel.add(myPreviousButton);
      }
      buttonPanel.add(Box.createHorizontalStrut(5));
      buttonPanel.add(myNextButton);
    } else {
      panel.add(buttonPanel, BorderLayout.CENTER);
      GroupLayout layout = new GroupLayout(buttonPanel);
      buttonPanel.setLayout(layout);
      layout.setAutoCreateGaps(true);

      final GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
      final GroupLayout.ParallelGroup vGroup = layout.createParallelGroup();
      final Collection<Component> buttons = ContainerUtil.newArrayListWithExpectedSize(5);
      final boolean helpAvailable = ApplicationInfo.contextHelpAvailable();

      if (helpAvailable && UIUtil.isUnderGTKLookAndFeel()) {
        add(hGroup, vGroup, buttons, myHelpButton);
      }
      add(hGroup, vGroup, null, Box.createHorizontalGlue());
      if (mySteps.size() > 1) {
        add(hGroup, vGroup, buttons, myPreviousButton);
      }
      add(hGroup, vGroup, buttons, myNextButton, myCancelButton);
      if (helpAvailable && !UIUtil.isUnderGTKLookAndFeel()) {
        add(hGroup, vGroup, buttons, myHelpButton);
      }

      layout.setHorizontalGroup(hGroup);
      layout.setVerticalGroup(vGroup);
      layout.linkSize(buttons.toArray(new Component[buttons.size()]));
    }

    myPreviousButton.setEnabled(false);
    myPreviousButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            doPreviousAction();
          }
        });
    myNextButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            if (isLastStep()) {
              // Commit data of current step and perform OK action
              final Step currentStep = mySteps.get(myCurrentStep);
              LOG.assertTrue(currentStep != null);
              try {
                currentStep._commit(true);
                doOKAction();
              } catch (final CommitStepException exc) {
                String message = exc.getMessage();
                if (message != null) {
                  Messages.showErrorDialog(myContentPanel, message);
                }
              }
            } else {
              doNextAction();
            }
          }
        });

    myCancelButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            doCancelAction();
          }
        });
    myHelpButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            helpAction();
          }
        });

    return panel;
  }
 public Color getHighlightColor() {
   return UIUtil.isUnderDarcula()
       ? UIUtil.getPanelBackground().brighter()
       : UIUtil.getTreeBackground().brighter();
 }
  @Override
  public void apply() {
    initComponent();
    UISettings settings = UISettings.getInstance();
    int _fontSize = getIntValue(myComponent.myFontSizeCombo, settings.FONT_SIZE);
    int _presentationFontSize =
        getIntValue(myComponent.myPresentationModeFontSize, settings.PRESENTATION_MODE_FONT_SIZE);
    boolean shouldUpdateUI = false;
    String _fontFace = (String) myComponent.myFontCombo.getSelectedItem();
    LafManager lafManager = LafManager.getInstance();
    if (_fontSize != settings.FONT_SIZE || !settings.FONT_FACE.equals(_fontFace)) {
      settings.FONT_SIZE = _fontSize;
      settings.FONT_FACE = _fontFace;
      shouldUpdateUI = true;
    }

    if (_presentationFontSize != settings.PRESENTATION_MODE_FONT_SIZE) {
      settings.PRESENTATION_MODE_FONT_SIZE = _presentationFontSize;
      shouldUpdateUI = true;
    }

    if (!myComponent.myAntialiasingInIDE.getSelectedItem().equals(settings.IDE_AA_TYPE)) {
      settings.IDE_AA_TYPE = (AntialiasingType) myComponent.myAntialiasingInIDE.getSelectedItem();
      shouldUpdateUI = true;
    }

    if (!myComponent.myAntialiasingInEditor.getSelectedItem().equals(settings.EDITOR_AA_TYPE)) {
      settings.EDITOR_AA_TYPE =
          (AntialiasingType) myComponent.myAntialiasingInEditor.getSelectedItem();
      shouldUpdateUI = true;
    }

    settings.ANIMATE_WINDOWS = myComponent.myAnimateWindowsCheckBox.isSelected();
    boolean update =
        settings.SHOW_TOOL_WINDOW_NUMBERS != myComponent.myWindowShortcutsCheckBox.isSelected();
    settings.SHOW_TOOL_WINDOW_NUMBERS = myComponent.myWindowShortcutsCheckBox.isSelected();
    update |= settings.HIDE_TOOL_STRIPES != !myComponent.myShowToolStripesCheckBox.isSelected();
    settings.HIDE_TOOL_STRIPES = !myComponent.myShowToolStripesCheckBox.isSelected();
    update |= settings.SHOW_ICONS_IN_MENUS != myComponent.myCbDisplayIconsInMenu.isSelected();
    settings.SHOW_ICONS_IN_MENUS = myComponent.myCbDisplayIconsInMenu.isSelected();
    update |=
        settings.SHOW_MEMORY_INDICATOR != myComponent.myShowMemoryIndicatorCheckBox.isSelected();
    settings.SHOW_MEMORY_INDICATOR = myComponent.myShowMemoryIndicatorCheckBox.isSelected();
    update |= settings.ALLOW_MERGE_BUTTONS != myComponent.myAllowMergeButtons.isSelected();
    settings.ALLOW_MERGE_BUTTONS = myComponent.myAllowMergeButtons.isSelected();
    update |= settings.CYCLE_SCROLLING != myComponent.myCycleScrollingCheckBox.isSelected();
    settings.CYCLE_SCROLLING = myComponent.myCycleScrollingCheckBox.isSelected();
    if (settings.OVERRIDE_NONIDEA_LAF_FONTS != myComponent.myOverrideLAFFonts.isSelected()) {
      shouldUpdateUI = true;
    }
    settings.OVERRIDE_NONIDEA_LAF_FONTS = myComponent.myOverrideLAFFonts.isSelected();
    settings.MOVE_MOUSE_ON_DEFAULT_BUTTON =
        myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected();
    settings.HIDE_NAVIGATION_ON_FOCUS_LOSS =
        myComponent.myHideNavigationPopupsCheckBox.isSelected();
    settings.DND_WITH_PRESSED_ALT_ONLY = myComponent.myAltDNDCheckBox.isSelected();

    update |= settings.DISABLE_MNEMONICS != myComponent.myDisableMnemonics.isSelected();
    settings.DISABLE_MNEMONICS = myComponent.myDisableMnemonics.isSelected();

    update |= settings.USE_SMALL_LABELS_ON_TABS != myComponent.myUseSmallLabelsOnTabs.isSelected();
    settings.USE_SMALL_LABELS_ON_TABS = myComponent.myUseSmallLabelsOnTabs.isSelected();

    update |= settings.WIDESCREEN_SUPPORT != myComponent.myWidescreenLayoutCheckBox.isSelected();
    settings.WIDESCREEN_SUPPORT = myComponent.myWidescreenLayoutCheckBox.isSelected();

    update |= settings.LEFT_HORIZONTAL_SPLIT != myComponent.myLeftLayoutCheckBox.isSelected();
    settings.LEFT_HORIZONTAL_SPLIT = myComponent.myLeftLayoutCheckBox.isSelected();

    update |= settings.RIGHT_HORIZONTAL_SPLIT != myComponent.myRightLayoutCheckBox.isSelected();
    settings.RIGHT_HORIZONTAL_SPLIT = myComponent.myRightLayoutCheckBox.isSelected();

    update |=
        settings.NAVIGATE_TO_PREVIEW
            != (myComponent.myNavigateToPreviewCheckBox.isVisible()
                && myComponent.myNavigateToPreviewCheckBox.isSelected());
    settings.NAVIGATE_TO_PREVIEW = myComponent.myNavigateToPreviewCheckBox.isSelected();

    ColorBlindness blindness = myComponent.myColorBlindnessPanel.getColorBlindness();
    boolean updateEditorScheme = false;
    if (settings.COLOR_BLINDNESS != blindness) {
      settings.COLOR_BLINDNESS = blindness;
      update = true;
      ComponentsPackage.getStateStore(ApplicationManager.getApplication())
          .reloadState(DefaultColorSchemesManager.class);
      updateEditorScheme = true;
    }

    update |=
        settings.DISABLE_MNEMONICS_IN_CONTROLS
            != myComponent.myDisableMnemonicInControlsCheckBox.isSelected();
    settings.DISABLE_MNEMONICS_IN_CONTROLS =
        myComponent.myDisableMnemonicInControlsCheckBox.isSelected();

    update |=
        settings.SHOW_ICONS_IN_QUICK_NAVIGATION
            != myComponent.myHideIconsInQuickNavigation.isSelected();
    settings.SHOW_ICONS_IN_QUICK_NAVIGATION = myComponent.myHideIconsInQuickNavigation.isSelected();

    if (!Comparing.equal(
        myComponent.myLafComboBox.getSelectedItem(), lafManager.getCurrentLookAndFeel())) {
      final UIManager.LookAndFeelInfo lafInfo =
          (UIManager.LookAndFeelInfo) myComponent.myLafComboBox.getSelectedItem();
      if (lafManager.checkLookAndFeel(lafInfo)) {
        update = shouldUpdateUI = true;
        final boolean wasDarcula = UIUtil.isUnderDarcula();
        lafManager.setCurrentLookAndFeel(lafInfo);
        //noinspection SSBasedInspection
        SwingUtilities.invokeLater(
            new Runnable() {
              @Override
              public void run() {
                if (UIUtil.isUnderDarcula()) {
                  DarculaInstaller.install();
                } else if (wasDarcula) {
                  DarculaInstaller.uninstall();
                }
              }
            });
      }
    }

    if (shouldUpdateUI) {
      lafManager.updateUI();
    }

    if (WindowManagerEx.getInstanceEx().isAlphaModeSupported()) {
      int delay = -1;
      try {
        delay = Integer.parseInt(myComponent.myAlphaModeDelayTextField.getText());
      } catch (NumberFormatException ignored) {
      }
      float ratio = myComponent.myAlphaModeRatioSlider.getValue() / 100f;
      if (myComponent.myEnableAlphaModeCheckBox.isSelected() != settings.ENABLE_ALPHA_MODE
          || delay != -1 && delay != settings.ALPHA_MODE_DELAY
          || ratio != settings.ALPHA_MODE_RATIO) {
        update = true;
        settings.ENABLE_ALPHA_MODE = myComponent.myEnableAlphaModeCheckBox.isSelected();
        settings.ALPHA_MODE_DELAY = delay;
        settings.ALPHA_MODE_RATIO = ratio;
      }
    }
    int tooltipDelay = Math.min(myComponent.myInitialTooltipDelaySlider.getValue(), 5000);
    if (tooltipDelay != Registry.intValue("ide.tooltip.initialDelay")) {
      update = true;
      Registry.get("ide.tooltip.initialDelay").setValue(tooltipDelay);
    }

    if (update) {
      settings.fireUISettingsChanged();
    }
    myComponent.updateCombo();

    EditorUtil.reinitSettings();

    if (updateEditorScheme) {
      EditorColorsManagerImpl.schemeChangedOrSwitched();
    }
  }
    private void doPaint(Graphics g) {
      GraphicsUtil.setupAntialiasing(g);

      final boolean isEmpty = getIcon() == null && StringUtil.isEmpty(getText());
      final Dimension size = getSize();
      if (isSmallVariant()) {
        final Graphics2D g2 = (Graphics2D) g;
        g2.setColor(UIUtil.getControlColor());
        final int w = getWidth();
        final int h = getHeight();
        if (getModel().isArmed() && getModel().isPressed()) {
          g2.setPaint(
              new GradientPaint(
                  0,
                  0,
                  UIUtil.getControlColor(),
                  0,
                  h,
                  ColorUtil.shift(UIUtil.getControlColor(), 0.8)));
        } else {
          g2.setPaint(
              new GradientPaint(
                  0,
                  0,
                  ColorUtil.shift(UIUtil.getControlColor(), 1.1),
                  0,
                  h,
                  ColorUtil.shift(UIUtil.getControlColor(), 0.9)));
        }
        g2.fillRect(2, 0, w - 2, h);
        GraphicsUtil.setupAntialiasing(g2);
        if (!myMouseInside) {
          g2.setPaint(
              new GradientPaint(
                  0, 0, UIUtil.getBorderColor(), 0, h, UIUtil.getBorderColor().darker()));
          // g2.setColor(UIUtil.getBorderColor());
        } else {
          g2.setPaint(
              new GradientPaint(
                  0,
                  0,
                  UIUtil.getBorderColor().darker(),
                  0,
                  h,
                  UIUtil.getBorderColor().darker().darker()));
        }
        g2.drawRect(2, 0, w - 3, h - 1);
        final Icon icon = getIcon();
        int x = 7;
        if (icon != null) {
          icon.paintIcon(null, g, x, (size.height - icon.getIconHeight()) / 2);
          x += icon.getIconWidth() + 3;
        }
        if (!StringUtil.isEmpty(getText())) {
          final Font font = getFont();
          g2.setFont(font);
          g2.setColor(UIManager.getColor("Panel.foreground"));
          g2.drawString(getText(), x, (size.height + font.getSize()) / 2 - 1);
        }
      } else {
        super.paintComponent(g);
      }
      final Insets insets = super.getInsets();
      final Icon icon = isEnabled() ? ARROW_ICON : DISABLED_ARROW_ICON;
      final int x;
      if (isEmpty) {
        x = (size.width - icon.getIconWidth()) / 2;
      } else {
        if (isSmallVariant()) {
          x = size.width - icon.getIconWidth() - insets.right + 1;
        } else {
          x =
              size.width
                  - icon.getIconWidth()
                  - insets.right
                  + (UIUtil.isUnderNimbusLookAndFeel() ? -3 : 2);
        }
      }
      if (UIUtil.isUnderDarcula()) {
        g.setXORMode(new Color(208, 188, 159));
      }
      icon.paintIcon(null, g, x, (size.height - icon.getIconHeight()) / 2);
      g.setPaintMode();
    }
Example #30
0
public final class IconLoader {
  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.IconLoader");
  public static boolean STRICT = false;
  private static boolean USE_DARK_ICONS = UIUtil.isUnderDarcula();
  private static float SCALE = JBUI.scale(1f);
  private static ImageFilter IMAGE_FILTER;

  @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
  private static final ConcurrentMap<URL, CachedImageIcon> ourIconsCache =
      ContainerUtil.newConcurrentMap(100, 0.9f, 2);

  /** This cache contains mapping between icons and disabled icons. */
  private static final Map<Icon, Icon> ourIcon2DisabledIcon = new WeakHashMap<Icon, Icon>(200);

  @NonNls
  private static final Map<String, String> ourDeprecatedIconsReplacements =
      new HashMap<String, String>();

  static {
    ourDeprecatedIconsReplacements.put(
        "/general/toolWindowDebugger.png", "AllIcons.Toolwindows.ToolWindowDebugger");
    ourDeprecatedIconsReplacements.put(
        "/general/toolWindowChanges.png", "AllIcons.Toolwindows.ToolWindowChanges");

    ourDeprecatedIconsReplacements.put(
        "/actions/showSettings.png", "AllIcons.General.ProjectSettings");
    ourDeprecatedIconsReplacements.put("/general/ideOptions.png", "AllIcons.General.Settings");
    ourDeprecatedIconsReplacements.put(
        "/general/applicationSettings.png", "AllIcons.General.Settings");
    ourDeprecatedIconsReplacements.put("/toolbarDecorator/add.png", "AllIcons.General.Add");
    ourDeprecatedIconsReplacements.put("/vcs/customizeView.png", "AllIcons.General.Settings");

    ourDeprecatedIconsReplacements.put("/vcs/refresh.png", "AllIcons.Actions.Refresh");
    ourDeprecatedIconsReplacements.put("/actions/sync.png", "AllIcons.Actions.Refresh");
    ourDeprecatedIconsReplacements.put("/actions/refreshUsages.png", "AllIcons.Actions.Rerun");

    ourDeprecatedIconsReplacements.put("/compiler/error.png", "AllIcons.General.Error");
    ourDeprecatedIconsReplacements.put(
        "/compiler/hideWarnings.png", "AllIcons.General.HideWarnings");
    ourDeprecatedIconsReplacements.put("/compiler/information.png", "AllIcons.General.Information");
    ourDeprecatedIconsReplacements.put("/compiler/warning.png", "AllIcons.General.Warning");
    ourDeprecatedIconsReplacements.put("/ide/errorSign.png", "AllIcons.General.Error");

    ourDeprecatedIconsReplacements.put("/ant/filter.png", "AllIcons.General.Filter");
    ourDeprecatedIconsReplacements.put("/inspector/useFilter.png", "AllIcons.General.Filter");

    ourDeprecatedIconsReplacements.put("/actions/showSource.png", "AllIcons.Actions.Preview");
    ourDeprecatedIconsReplacements.put(
        "/actions/consoleHistory.png", "AllIcons.General.MessageHistory");
    ourDeprecatedIconsReplacements.put(
        "/vcs/messageHistory.png", "AllIcons.General.MessageHistory");
  }

  private static final ImageIcon EMPTY_ICON =
      new ImageIcon(UIUtil.createImage(1, 1, BufferedImage.TYPE_3BYTE_BGR)) {
        @NonNls
        public String toString() {
          return "Empty icon " + super.toString();
        }
      };

  private static boolean ourIsActivated = false;

  private IconLoader() {}

  @Deprecated
  public static Icon getIcon(@NotNull final Image image) {
    return new JBImageIcon(image);
  }

  public static void setUseDarkIcons(boolean useDarkIcons) {
    USE_DARK_ICONS = useDarkIcons;
    clearCache();
  }

  public static void setScale(float scale) {
    if (scale != SCALE) {
      SCALE = scale;
      clearCache();
    }
  }

  public static void setFilter(ImageFilter filter) {
    if (!Registry.is("color.blindness.icon.filter")) {
      filter = null;
    }
    if (IMAGE_FILTER != filter) {
      IMAGE_FILTER = filter;
      clearCache();
    }
  }

  private static void clearCache() {
    ourIconsCache.clear();
    ourIcon2DisabledIcon.clear();
  }

  // TODO[kb] support iconsets
  // public static Icon getIcon(@NotNull final String path, @NotNull final String darkVariantPath) {
  //  return new InvariantIcon(getIcon(path), getIcon(darkVariantPath));
  // }

  @NotNull
  public static Icon getIcon(@NonNls @NotNull final String path) {
    Class callerClass = ReflectionUtil.getGrandCallerClass();

    assert callerClass != null : path;
    return getIcon(path, callerClass);
  }

  @Nullable
  private static Icon getReflectiveIcon(@NotNull String path, ClassLoader classLoader) {
    try {
      @NonNls String pckg = path.startsWith("AllIcons.") ? "com.intellij.icons." : "icons.";
      Class cur =
          Class.forName(
              pckg + path.substring(0, path.lastIndexOf('.')).replace('.', '$'), true, classLoader);
      Field field = cur.getField(path.substring(path.lastIndexOf('.') + 1));

      return (Icon) field.get(null);
    } catch (Exception e) {
      return null;
    }
  }

  @Nullable
  /**
   * Might return null if icon was not found. Use only if you expected null return value, otherwise
   * see {@link IconLoader#getIcon(java.lang.String)}
   */
  public static Icon findIcon(@NonNls @NotNull String path) {
    Class callerClass = ReflectionUtil.getGrandCallerClass();
    if (callerClass == null) return null;
    return findIcon(path, callerClass);
  }

  @NotNull
  public static Icon getIcon(@NotNull String path, @NotNull final Class aClass) {
    final Icon icon = findIcon(path, aClass);
    if (icon == null) {
      LOG.error("Icon cannot be found in '" + path + "', aClass='" + aClass + "'");
    }
    return icon;
  }

  public static void activate() {
    ourIsActivated = true;
  }

  private static boolean isLoaderDisabled() {
    return !ourIsActivated;
  }

  /**
   * Might return null if icon was not found. Use only if you expected null return value, otherwise
   * see {@link IconLoader#getIcon(java.lang.String, java.lang.Class)}
   */
  @Nullable
  public static Icon findIcon(@NotNull final String path, @NotNull final Class aClass) {
    return findIcon(path, aClass, false);
  }

  @Nullable
  public static Icon findIcon(
      @NotNull String path, @NotNull final Class aClass, boolean computeNow) {
    path = undeprecate(path);
    if (isReflectivePath(path)) return getReflectiveIcon(path, aClass.getClassLoader());

    URL myURL = aClass.getResource(path);
    if (myURL == null) {
      if (STRICT) throw new RuntimeException("Can't find icon in '" + path + "' near " + aClass);
      return null;
    }
    return findIcon(myURL);
  }

  @NotNull
  private static String undeprecate(@NotNull String path) {
    String replacement = ourDeprecatedIconsReplacements.get(path);
    return replacement == null ? path : replacement;
  }

  private static boolean isReflectivePath(@NotNull String path) {
    List<String> paths = StringUtil.split(path, ".");
    return paths.size() > 1 && paths.get(0).endsWith("Icons");
  }

  @Nullable
  public static Icon findIcon(URL url) {
    return findIcon(url, true);
  }

  @Nullable
  public static Icon findIcon(URL url, boolean useCache) {
    if (url == null) {
      return null;
    }
    CachedImageIcon icon = ourIconsCache.get(url);
    if (icon == null) {
      icon = new CachedImageIcon(url);
      if (useCache) {
        icon = ConcurrencyUtil.cacheOrGet(ourIconsCache, url, icon);
      }
    }
    return icon;
  }

  @Nullable
  public static Icon findIcon(@NotNull String path, @NotNull ClassLoader classLoader) {
    path = undeprecate(path);
    if (isReflectivePath(path)) return getReflectiveIcon(path, classLoader);
    if (!StringUtil.startsWithChar(path, '/')) return null;

    final URL url = classLoader.getResource(path.substring(1));
    return findIcon(url);
  }

  @Nullable
  private static Icon checkIcon(final Image image, @NotNull URL url) {
    if (image == null
        || image.getHeight(LabelHolder.ourFakeComponent) < 1) { // image wasn't loaded or broken
      return null;
    }

    final Icon icon = getIcon(image);
    if (icon != null && !isGoodSize(icon)) {
      LOG.error("Invalid icon: " + url); // # 22481
      return EMPTY_ICON;
    }
    return icon;
  }

  public static boolean isGoodSize(@NotNull final Icon icon) {
    return icon.getIconWidth() > 0 && icon.getIconHeight() > 0;
  }

  /**
   * Gets (creates if necessary) disabled icon based on the passed one.
   *
   * @return <code>ImageIcon</code> constructed from disabled image of passed icon.
   */
  @Nullable
  public static Icon getDisabledIcon(Icon icon) {
    if (icon instanceof LazyIcon) icon = ((LazyIcon) icon).getOrComputeIcon();
    if (icon == null) return null;

    Icon disabledIcon = ourIcon2DisabledIcon.get(icon);
    if (disabledIcon == null) {
      if (!isGoodSize(icon)) {
        LOG.error(icon); // # 22481
        return EMPTY_ICON;
      }
      final int scale = UIUtil.isRetina() ? 2 : 1;
      @SuppressWarnings("UndesirableClassUsage")
      BufferedImage image =
          new BufferedImage(
              scale * icon.getIconWidth(),
              scale * icon.getIconHeight(),
              BufferedImage.TYPE_INT_ARGB);
      final Graphics2D graphics = image.createGraphics();

      graphics.setColor(UIUtil.TRANSPARENT_COLOR);
      graphics.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight());
      graphics.scale(scale, scale);
      icon.paintIcon(LabelHolder.ourFakeComponent, graphics, 0, 0);

      graphics.dispose();

      Image img = ImageUtil.filter(image, UIUtil.getGrayFilter());
      if (UIUtil.isRetina()) img = RetinaImage.createFrom(img, 2, ImageLoader.ourComponent);

      disabledIcon = new JBImageIcon(img);
      ourIcon2DisabledIcon.put(icon, disabledIcon);
    }
    return disabledIcon;
  }

  public static Icon getTransparentIcon(@NotNull final Icon icon) {
    return getTransparentIcon(icon, 0.5f);
  }

  public static Icon getTransparentIcon(@NotNull final Icon icon, final float alpha) {
    return new Icon() {
      @Override
      public int getIconHeight() {
        return icon.getIconHeight();
      }

      @Override
      public int getIconWidth() {
        return icon.getIconWidth();
      }

      @Override
      public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
        final Graphics2D g2 = (Graphics2D) g;
        final Composite saveComposite = g2.getComposite();
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
        icon.paintIcon(c, g2, x, y);
        g2.setComposite(saveComposite);
      }
    };
  }

  private static final class CachedImageIcon implements ScalableIcon {
    private Object myRealIcon;
    @NotNull private final URL myUrl;
    private boolean dark;
    private float scale;
    private ImageFilter filter;
    private HashMap<Float, Icon> scaledIcons;

    public CachedImageIcon(@NotNull URL url) {
      myUrl = url;
      dark = USE_DARK_ICONS;
      scale = SCALE;
      filter = IMAGE_FILTER;
    }

    @NotNull
    private synchronized Icon getRealIcon() {
      if (isLoaderDisabled()
          && (myRealIcon == null
              || dark != USE_DARK_ICONS
              || scale != SCALE
              || filter != IMAGE_FILTER)) return EMPTY_ICON;

      if (dark != USE_DARK_ICONS || scale != SCALE || filter != IMAGE_FILTER) {
        myRealIcon = null;
        dark = USE_DARK_ICONS;
        scale = SCALE;
        filter = IMAGE_FILTER;
      }
      Object realIcon = myRealIcon;
      if (realIcon instanceof Icon) return (Icon) realIcon;

      Icon icon;
      if (realIcon instanceof Reference) {
        icon = ((Reference<Icon>) realIcon).get();
        if (icon != null) return icon;
      }

      Image image = ImageLoader.loadFromUrl(myUrl, true, filter);
      icon = checkIcon(image, myUrl);

      if (icon != null) {
        if (icon.getIconWidth() < 50 && icon.getIconHeight() < 50) {
          realIcon = icon;
        } else {
          realIcon = new SoftReference<Icon>(icon);
        }
        myRealIcon = realIcon;
      }

      return icon == null ? EMPTY_ICON : icon;
    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
      getRealIcon().paintIcon(c, g, x, y);
    }

    @Override
    public int getIconWidth() {
      return getRealIcon().getIconWidth();
    }

    @Override
    public int getIconHeight() {
      return getRealIcon().getIconHeight();
    }

    @Override
    public String toString() {
      return myUrl.toString();
    }

    @Override
    public Icon scale(float scaleFactor) {
      if (scaleFactor == 1f) {
        return this;
      }
      if (scaledIcons == null) {
        scaledIcons = new HashMap<Float, Icon>(1);
      }

      Icon result = scaledIcons.get(scaleFactor);
      if (result != null) {
        return result;
      }

      final Image image =
          ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), scaleFactor >= 1.5f, filter);
      if (image != null) {
        int width = (int) (getIconWidth() * scaleFactor);
        int height = (int) (getIconHeight() * scaleFactor);
        final BufferedImage resizedImage =
            Scalr.resize(
                ImageUtil.toBufferedImage(image), Scalr.Method.ULTRA_QUALITY, width, height);
        result = getIcon(resizedImage);
        scaledIcons.put(scaleFactor, result);
        return result;
      }

      return this;
    }
  }

  public abstract static class LazyIcon implements Icon {
    private boolean myWasComputed;
    private Icon myIcon;
    private boolean isDarkVariant = USE_DARK_ICONS;
    private float scale = SCALE;
    private ImageFilter filter = IMAGE_FILTER;

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
      final Icon icon = getOrComputeIcon();
      if (icon != null) {
        icon.paintIcon(c, g, x, y);
      }
    }

    @Override
    public int getIconWidth() {
      final Icon icon = getOrComputeIcon();
      return icon != null ? icon.getIconWidth() : 0;
    }

    @Override
    public int getIconHeight() {
      final Icon icon = getOrComputeIcon();
      return icon != null ? icon.getIconHeight() : 0;
    }

    protected final synchronized Icon getOrComputeIcon() {
      if (!myWasComputed
          || isDarkVariant != USE_DARK_ICONS
          || scale != SCALE
          || filter != IMAGE_FILTER) {
        isDarkVariant = USE_DARK_ICONS;
        scale = SCALE;
        filter = IMAGE_FILTER;
        myWasComputed = true;
        myIcon = compute();
      }

      return myIcon;
    }

    public final void load() {
      getIconWidth();
    }

    protected abstract Icon compute();
  }

  private static class LabelHolder {
    /**
     * To get disabled icon with paint it into the image. Some icons require not null component to
     * paint.
     */
    private static final JComponent ourFakeComponent = new JLabel();
  }
}