JComponent () { final int selectionMode = myAllowMultipleSelections ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION; myList.setSelectionMode(selectionMode); if (myUseIdeaEditor) { EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); myList.setFont(scheme.getFont(EditorFontType.PLAIN)); Color fg = ObjectUtils.chooseNotNull(scheme.getDefaultForeground(), JBColor.lazy(UIUtil::getListForeground)); Color bg = ObjectUtils.chooseNotNull(scheme.getDefaultBackground(), JBColor.lazy(UIUtil::getListBackground)); myList.setForeground(fg); myList.setBackground(bg); } new DoubleClickListener() { @Override protected boolean onDoubleClick(@NotNull MouseEvent e) { close(OK_EXIT_CODE); return true; } }.installOn(myList); MyListCellRenderer renderer = new MyListCellRenderer(); myList.setCellRenderer(renderer); myList.addKeyListener(new KeyListener() { boolean doConsume; @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_DELETE) { int newSelectionIndex = -1; for (Item o : myList.getSelectedValuesList()) { int i = o.index; removeContentAt(myAllContents.get(i)); if (newSelectionIndex < 0) { newSelectionIndex = i; } } rebuildListContent(); if (myAllContents.isEmpty()) { close(CANCEL_EXIT_CODE); return; } newSelectionIndex = Math.min(newSelectionIndex, myAllContents.size() - 1); myList.setSelectedIndex(newSelectionIndex); } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { doOKAction(); } else if (myUseNumbering) { SpeedSearchSupply supply = SpeedSearchSupply.getSupply(myList); if (supply != null && supply.isPopupActive()) return; char aChar = e.getKeyChar(); if (aChar >= '0' && aChar <= '9') { int idx = aChar == '0' ? 9 : aChar - '1'; if (idx < myAllContents.size()) { myList.setSelectedIndex(idx); e.consume(); doConsume = true; // postpone doOKAction in order to handle all other (typed/released) key events // otherwise this events get to editor ApplicationManager.getApplication().invokeLater(() -> doOKAction()); } } } } @Override public void keyTyped(KeyEvent e) { // we handle keyPressed for numbers and close dialog but we have to handle typed and released events too if (doConsume) { e.consume(); } } @Override public void keyReleased(KeyEvent e) { // we handle keyPressed for numbers and close dialog but we have to handle typed and released events too if (doConsume) { e.consume(); } } }); mySplitter.setFirstComponent(ListWithFilter.wrap( myList, ScrollPaneFactory.createScrollPane(myList), o -> o.getShortText(renderer.previewChars), true)); mySplitter.setSecondComponent(new JPanel()); mySplitter.getFirstComponent().addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { FontMetrics metrics = myList.getFontMetrics(myList.getFont()); int charWidth = metrics.charWidth('i'); renderer.previewChars = myList.getParent().getParent().getWidth() / charWidth + 10; } }); rebuildListContent(); ScrollingUtil.installActions(myList); ScrollingUtil.ensureSelectionExists(myList); updateViewerForSelection(); myList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (myUpdateAlarm.isDisposed()) return; myUpdateAlarm.cancelAllRequests(); myUpdateAlarm.addRequest(() -> updateViewerForSelection(), 100); } }); mySplitter.setPreferredSize(JBUI.size(500, 500)); SplitterProportionsData d = new SplitterProportionsDataImpl(); d.externalizeToDimensionService(getClass().getName()); d.restoreSplitterProportions(mySplitter); return mySplitter; }