void (@Nullable ValidationInfo info) { if (disableValidation) return; boolean hasNewInfo = info != null && !info.equals(validationInfo); if (needResetForInfo(info)) { reset(); } if (hasNewInfo || (info != null && popup != null && !popup.isVisible())) { validationInfo = info; if (popup != null && popup.isVisible() && tipComponent != null) { popup.pack(true, convertMessage(info.message, tipComponent)); } else { JComponent component = validationInfo.component; if (component != null) { outlineProvider.apply(component).putClientProperty("JComponent.outline", validationInfo.warning ? "warning" : "error"); component.revalidate(); component.repaint(); } if (!StringUtil.isEmptyOrSpaces(info.message)) { // create popup if there is something to show to user popupBuilder = createPopupBuilder(validationInfo, editorPane -> { tipComponent = editorPane; editorPane.addHyperlinkListener(hyperlinkListener); editorPane.addMouseListener(new TipComponentMouseListener()); popupSize = editorPane.getPreferredSize(); }).setCancelOnMouseOutCallback(e -> e.getID() == MouseEvent.MOUSE_PRESSED && !withinComponent(info, e)); getFocusable(component).ifPresent(fc -> { if (fc.hasFocus()) { showPopup(); } }); } } } }