Component (JList<? extends AnAction> list, AnAction value, int index, boolean selected, boolean focused) { final Color fore = getListForeground(selected, list.hasFocus()); final Color back = getListBackground(selected, list.hasFocus()); final JLabel name = new JLabel(); final JLabel path = ComponentPanelBuilder.createNonWrappingCommentComponent(""); name.setForeground(fore); path.setForeground(NamedColorUtil.getInactiveTextColor()); setBackground(back); return new JPanel() { { setLayout(new BorderLayout()); setBackground(back); boolean isGroup = value instanceof ProjectGroupActionGroup; boolean isInsideGroup = false; if (value instanceof ReopenProjectAction) { final String path = ((ReopenProjectAction)value).getProjectPath(); for (ProjectGroup group : RecentProjectsManager.getInstance().getGroups()) { final List<String> projects = group.getProjects(); if (projects.contains(path)) { isInsideGroup = true; break; } } } setBorder(JBUI.Borders.empty(8, 7)); if (isInsideGroup) { add(spacer, BorderLayout.WEST); } if (isGroup) { final ProjectGroup group = ((ProjectGroupActionGroup)value).getGroup(); name.setText(" " + group.getName()); name.setIcon(IconUtil.toSize(group.isExpanded() ? UIUtil.getTreeExpandedIcon() : UIUtil.getTreeCollapsedIcon(), JBUIScale.scale(16), JBUIScale.scale(16))); name.setFont(name.getFont().deriveFont(Font.BOLD)); add(name); } else if (value instanceof ReopenProjectAction) { final NonOpaquePanel p = new NonOpaquePanel(new BorderLayout()); name.setText(((ReopenProjectAction)value).getProjectNameToDisplay()); final String realPath = PathUtil.toSystemDependentName(((ReopenProjectAction)value).getProjectPath()); int i = isInsideGroup ? 80 : 60; path.setText(getTitle2Text((ReopenProjectAction)value, path, JBUIScale.scale(i))); if (!realPath.equals(path.getText())) { projectsWithLongPaths.add((ReopenProjectAction)value); } boolean isValid = !isPathValid((((ReopenProjectAction)value).getProjectPath())); if (isValid) { name.setForeground(NamedColorUtil.getInactiveTextColor()); } p.add(name, BorderLayout.NORTH); p.add(path, BorderLayout.SOUTH); p.setBorder(JBUI.Borders.emptyRight(30)); String projectPath = ((ReopenProjectAction)value).getProjectPath(); RecentProjectsManagerBase recentProjectsManage = RecentProjectsManagerBase.getInstanceEx(); Icon icon = recentProjectsManage.getProjectIcon(projectPath, true); final JLabel projectIcon = new JLabel("", icon, SwingConstants.LEFT) { @Override protected void paintComponent(Graphics g) { Icon icon = isEnabled() ? getIcon() : getDisabledIcon(); icon.paintIcon(this, g, 0, 0); } }; ApplicationManager.getApplication().executeOnPooledThread(() -> { // IconUtil.desaturate eagerly evaluates `icon` which // may take unbound amount of time on a network share Icon disabledIcon = IconUtil.desaturate(icon); ApplicationManager.getApplication().invokeLater(() -> { if (projectIcon.isValid()) { projectIcon.setDisabledIcon(disabledIcon); } }, ModalityState.any()); }); if (isValid) { projectIcon.setEnabled(false); } projectIcon.setBorder(JBUI.Borders.emptyRight(8)); projectIcon.setVerticalAlignment(SwingConstants.CENTER); final NonOpaquePanel panel = new NonOpaquePanel(new BorderLayout()); panel.add(p); panel.add(projectIcon, BorderLayout.WEST); add(panel); } AccessibleContextUtil.setCombinedName(this, name, " - ", path); AccessibleContextUtil.setCombinedDescription(this, name, " - ", path); } private static Icon getGray(Icon icon) { final int w = icon.getIconWidth(); final int h = icon.getIconHeight(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage image = gc.createCompatibleImage(w, h); Graphics2D g2d = image.createGraphics(); icon.paintIcon(null, g2d, 0, 0); Image gray = GrayFilter.createDisabledImage(image); return new ImageIcon(gray); } @Override public Dimension getPreferredSize() { return new Dimension(super.getPreferredSize().width, JBUIScale.scale(value instanceof ProjectGroupActionGroup ? 32 : 50)); } }; }