void (@NotNull Project project, boolean showChanged, @NotNull @NlsContexts.PopupTitle String title1, @NotNull @NlsContexts.PopupTitle String title2, @NotNull @NlsContexts.StatusText String emptyText, @Nullable Function<? super Boolean, ? extends List<IdeDocumentHistoryImpl.PlaceInfo>> supplier, @Nullable Consumer<? super List<IdeDocumentHistoryImpl.PlaceInfo>> remover) { RecentLocationsDataModel model = new RecentLocationsDataModel(project, supplier, remover); JBList<RecentLocationItem> list = new JBList<>(JBList.createDefaultListModel(model.getPlaces(showChanged))); final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setBorder(BorderFactory.createEmptyBorder()); ShortcutSet showChangedOnlyShortcutSet = KeymapUtil.getActiveKeymapShortcuts(RECENT_LOCATIONS_ACTION_ID); JBCheckBox checkBox = createCheckbox(showChangedOnlyShortcutSet, showChanged); RecentLocationsRenderer renderer = new RecentLocationsRenderer(project, model, checkBox); list.setCellRenderer(renderer); list.setEmptyText(emptyText); list.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground()); if (list.getModel().getSize() > 0) list.setSelectedIndex(0); ScrollingUtil.installActions(list); SimpleColoredComponent title = new SimpleColoredComponent(); title.setOpaque(false); Runnable titleUpdater = () -> { title.clear(); title.append(checkBox.isSelected() ? title2 : title1, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); title.append(" (" + list.getModel().getSize() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); }; titleUpdater.run(); JComponent listWithFilter = ListWithFilter.wrap(list, scrollPane, renderer::getSpeedSearchText, true); //noinspection unchecked ((ListWithFilter<Object>)listWithFilter).setAutoPackHeight(false); listWithFilter.setBorder(BorderFactory.createEmptyBorder()); JPanel topPanel = createHeaderPanel(title, checkBox); JPanel mainPanel = createMainPanel(listWithFilter, topPanel); Color borderColor = SystemInfo.isMac && LafManager.getInstance().getCurrentUIThemeLookAndFeel().isDark() ? topPanel.getBackground() : null; JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(mainPanel, list) .setProject(project) .setCancelOnClickOutside(true) .setRequestFocus(true) .setResizable(true) .setMovable(true) .setBorderColor(borderColor) .setDimensionServiceKey(project, LOCATION_SETTINGS_KEY, true) .setMinSize(new Dimension(getMinimumWidth(), getMinimumHeight())) .setLocateWithinScreenBounds(false) .createPopup(); Disposer.register(popup, renderer); LightEditActionFactory.create(event -> { checkBox.setSelected(!checkBox.isSelected()); updateItems(model, list, checkBox, popup); titleUpdater.run(); }).registerCustomShortcutSet(showChangedOnlyShortcutSet, list, popup); checkBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateItems(model, list, checkBox, popup); titleUpdater.run(); } }); if (DimensionService.getInstance().getSize(LOCATION_SETTINGS_KEY, project) == null) { popup.setSize(new Dimension(getDefaultWidth(), getDefaultHeight())); } list.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent event) { int clickCount = event.getClickCount(); if (clickCount > 1 && clickCount % 2 == 0) { event.consume(); final int i = list.locationToIndex(event.getPoint()); if (i != -1) { list.setSelectedIndex(i); navigateToSelected(project, list, popup); } } } }); list.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent event) { int clickCount = event.getClickCount(); if (clickCount > 1 && clickCount % 2 == 0) { event.consume(); navigateToSelected(project, list, popup); } } }); LightEditActionFactory.create(e -> navigateToSelected(project, list, popup)) .registerCustomShortcutSet(CustomShortcutSet.fromString("ENTER"), list, popup); LightEditActionFactory.create(e -> { removeItems(project, list, model, checkBox.isSelected()); titleUpdater.run(); }) .registerCustomShortcutSet(CustomShortcutSet.fromString("DELETE", "BACK_SPACE"), list, popup); IdeEventQueue.getInstance().getPopupManager().closeAllPopups(false); list.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { if (!(e.getOppositeComponent() instanceof JCheckBox)) { popup.cancel(); } } }); showPopup(project, popup); }