JBPopup (List<? extends GrParameterListOwner> scopes, final Editor editor, final JBPopupOwner popupRef, final PairFunction<? super GrParameterListOwner, ? super PsiElement, Object> callback) { final JPanel panel = new JPanel(new BorderLayout()); final JCheckBox superMethod = new JCheckBox(GroovyBundle.message("change.base.method.label"), true); superMethod.setMnemonic(KeyEvent.VK_U); panel.add(superMethod, BorderLayout.SOUTH); final JBList list = new JBList(scopes.toArray()); list.setVisibleRowCount(5); list.setCellRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); final String text; if (value instanceof PsiMethod method) { text = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_TYPE); final int flags = Iconable.ICON_FLAG_VISIBILITY; final Icon icon = method.getIcon(flags); if (icon != null) setIcon(icon); } else { LOG.assertTrue(value instanceof GrClosableBlock); setIcon(JetgroovyIcons.Groovy.Groovy_16x16); text = "{...}"; } setText(text); return this; } }); list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); final List<RangeHighlighter> highlighters = new ArrayList<>(); list.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(final ListSelectionEvent e) { final GrParameterListOwner selectedMethod = (GrParameterListOwner)list.getSelectedValue(); if (selectedMethod == null) return; dropHighlighters(highlighters); updateView(selectedMethod, editor, EditorColors.SEARCH_RESULT_ATTRIBUTES, highlighters, superMethod); } }); updateView(scopes.get(0), editor, EditorColors.SEARCH_RESULT_ATTRIBUTES, highlighters, superMethod); final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(list); scrollPane.setBorder(null); panel.add(scrollPane, BorderLayout.CENTER); final List<Pair<ActionListener, KeyStroke>> keyboardActions = Collections.singletonList( Pair.create(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final GrParameterListOwner ToSearchIn = (GrParameterListOwner)list.getSelectedValue(); final JBPopup popup = popupRef.get(); if (popup != null && popup.isVisible()) { popup.cancel(); } final PsiElement toSearchFor; if (ToSearchIn instanceof GrMethod method) { toSearchFor = superMethod.isEnabled() && superMethod.isSelected() ? method.findDeepestSuperMethod() : method; } else { toSearchFor = superMethod.isEnabled() && superMethod.isSelected() ? ToSearchIn.getParent() : null; } IdeFocusManager.findInstance().doWhenFocusSettlesDown(() -> callback.fun(ToSearchIn, toSearchFor), ModalityState.current()); } }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0))); return JBPopupFactory.getInstance().createComponentPopupBuilder(panel, list) .setTitle(GroovyBundle.message("parameter.list.owner.chooser.title")) .setMovable(false) .setResizable(false) .setRequestFocus(true) .setKeyboardActions(keyboardActions).addListener(new JBPopupListener() { @Override public void onClosed(@NotNull LightweightWindowEvent event) { dropHighlighters(highlighters); } }).createPopup(); }