void (final @NotNull CustomTemplateCallback customTemplateCallback) { if (ApplicationManager.getApplication().isUnitTestMode()) { if (ourTestingAbbreviation == null) { throw new RuntimeException("Testing abbreviation is not set. See EmmetAbbreviationBalloon#setTestingAbbreviation"); } myCallback.onEnter(ourTestingAbbreviation); return; } JPanel panel = new JPanel(new BorderLayout()); final TextFieldWithStoredHistory field = new TextFieldWithStoredHistory(myAbbreviationsHistoryKey); final Dimension fieldPreferredSize = field.getPreferredSize(); field.setPreferredSize(new Dimension(Math.max(220, fieldPreferredSize.width), fieldPreferredSize.height)); field.setHistorySize(10); ContextHelpLabel label = myContextHelp.createHelpLabel(); label.setBorder(JBUI.Borders.empty(0, 3, 0, 1)); panel.add(field, BorderLayout.CENTER); panel.add(label, BorderLayout.EAST); final JBPopupFactory popupFactory = JBPopupFactory.getInstance(); final Balloon balloon = popupFactory.createBalloonBuilder(panel) .setCloseButtonEnabled(false) .setBlockClicksThroughBalloon(true) .setAnimationCycle(0) .setHideOnKeyOutside(true) .setHideOnClickOutside(true) .setFillColor(panel.getBackground()) .createBalloon(); final DocumentAdapter documentListener = new DocumentAdapter() { @Override protected void textChanged(@NotNull DocumentEvent e) { if (!isValid(customTemplateCallback)) { balloon.hide(); return; } validateTemplateKey(field, balloon, field.getText(), customTemplateCallback); } }; field.addDocumentListener(documentListener); final KeyAdapter keyListener = new KeyAdapter() { @Override public void keyPressed(@NotNull KeyEvent e) { if (!field.isPopupVisible()) { if (!isValid(customTemplateCallback)) { balloon.hide(); return; } switch (e.getKeyCode()) { case KeyEvent.VK_ENTER -> { final String abbreviation = field.getText(); if (validateTemplateKey(field, balloon, abbreviation, customTemplateCallback)) { myCallback.onEnter(abbreviation); PropertiesComponent.getInstance().setValue(myLastAbbreviationKey, abbreviation); field.addCurrentTextToHistory(); balloon.hide(); } } case KeyEvent.VK_ESCAPE -> balloon.hide(false); } } } }; field.addKeyboardListener(keyListener); balloon.addListener(new JBPopupListener() { @Override public void beforeShown(@NotNull LightweightWindowEvent event) { field.setText(PropertiesComponent.getInstance().getValue(myLastAbbreviationKey, "")); } @Override public void onClosed(@NotNull LightweightWindowEvent event) { field.removeKeyListener(keyListener); field.removeDocumentListener(documentListener); } }); balloon.show(popupFactory.guessBestPopupLocation(customTemplateCallback.getEditor()), Balloon.Position.below); final IdeFocusManager focusManager = IdeFocusManager.getInstance(customTemplateCallback.getProject()); focusManager.doWhenFocusSettlesDown(() -> { focusManager.requestFocus(field, true); field.selectText(); }); }