JComponent () { final JPanel panel = new JPanel(new BorderLayout()); DataManager.registerDataProvider(panel, dataId -> { final TreePath path = myTree.getSelectionPath(); if (path != null) { Object component = path.getLastPathComponent(); VirtualFile file = null; if (component instanceof MyFileNode) { component = ((MyFileNode)component).getParent(); } if (component instanceof MyDuplicatesNode) { file = ((MyDuplicatesNode)component).getUserObject().iterator().next(); } if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) { return file; } if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId) && file != null) { return new VirtualFile[]{file}; } } return null; }); JBList<String> list = new JBList<>(new ResourceModules().getModuleNames()); final NotNullFunction<Object, JComponent> modulesRenderer = dom -> new JLabel(dom instanceof Module ? ((Module)dom).getName() : dom.toString(), PlatformIcons.SOURCE_FOLDERS_ICON, SwingConstants.LEFT); list.installCellRenderer(modulesRenderer); final JPanel modulesPanel = ToolbarDecorator.createDecorator(list) .setAddAction(button -> { final Module[] all = ModuleManager.getInstance(myProject).getModules(); Arrays.sort(all, Comparator.comparing(Module::getName)); JBList<Module> modules = new JBList<>(all); modules.installCellRenderer(modulesRenderer); JBPopupFactory.getInstance().createListPopupBuilder(modules) .setTitle("Add Resource Module") .setNamerForFiltering(o -> o.getName()) .setItemChosenCallback(() -> { Module value = modules.getSelectedValue(); if (value != null && !myResourceModules.contains(value)) { myResourceModules.add(value); ((DefaultListModel<String>)list.getModel()).addElement(value.getName()); } ((DefaultTreeModel)myTree.getModel()).reload(); TreeUtil.expandAll(myTree); }).createPopup().show(button.getPreferredPopupPoint()); }) .setRemoveAction(button -> { final Object[] values = list.getSelectedValues(); for (Object value : values) { myResourceModules.remove((String)value); ((DefaultListModel<String>)list.getModel()).removeElement(value); } ((DefaultTreeModel)myTree.getModel()).reload(); TreeUtil.expandAll(myTree); }) .disableDownAction() .disableUpAction() .createPanel(); modulesPanel.setPreferredSize(new Dimension(-1, 60)); final JPanel top = new JPanel(new BorderLayout()); top.add(new JLabel("Image modules:"), BorderLayout.NORTH); top.add(modulesPanel, BorderLayout.CENTER); panel.add(top, BorderLayout.NORTH); panel.add(new JBScrollPane(myTree), BorderLayout.CENTER); new AnAction() { @Override public void actionPerformed(@NotNull AnActionEvent e) { VirtualFile file = getFileFromSelection(); if (file != null) { final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file); if (psiFile != null) { final ImplementationViewComponent viewComponent = new ImplementationViewComponent(Collections.singletonList(new PsiImplementationViewElement(psiFile)), 0); final TreeSelectionListener listener = e1 -> { final VirtualFile selection = getFileFromSelection(); if (selection != null) { final PsiFile newElement = PsiManager.getInstance(myProject).findFile(selection); if (newElement != null) { viewComponent.update(Collections.singletonList(new PsiImplementationViewElement(newElement)), 0); } } }; myTree.addTreeSelectionListener(listener); final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(viewComponent, viewComponent.getPreferredFocusableComponent()) .setProject(myProject) .setDimensionServiceKey(myProject, ImageDuplicateResultsDialog.class.getName(), false) .setResizable(true) .setMovable(true) .setRequestFocus(false) .addListener(new JBPopupListener() { @Override public void onClosed(@NotNull LightweightWindowEvent event) { viewComponent.cleanup(); } }) .setCancelCallback(() -> { myTree.removeTreeSelectionListener(listener); return true; }) .setTitle("Image Preview") .createPopup(); final Window window = ImageDuplicateResultsDialog.this.getWindow(); popup.show(new RelativePoint(window, new Point(window.getWidth(), 0))); viewComponent.setHint(popup, "Image Preview"); } } } }.registerCustomShortcutSet(CustomShortcutSet.fromString("ENTER"), panel); int total = myDuplicates.values().stream().mapToInt(Set::size).sum() - myDuplicates.size(); final JLabel label = new JLabel( "<html>Press <b>Enter</b> to preview image<br>Total images found: " + myImages.size() + ". Total duplicates found: " + total+"</html>"); panel.add(label, BorderLayout.SOUTH); return panel; }