void (final @NotNull LafManager lafManager, @NotNull UIThemeLookAndFeelInfo lf, boolean async, boolean force, boolean lockEditorScheme) { UIThemeLookAndFeelInfo cur = lafManager.getCurrentUIThemeLookAndFeel(); if (!force && cur == lf) return; ChangeLAFAnimator animator = Registry.is("ide.intellij.laf.enable.animation") ? ChangeLAFAnimator.showSnapshot() : null; final boolean wasDarcula = StartupUiUtil.isUnderDarcula(); lafManager.setCurrentLookAndFeel(lf, lockEditorScheme); Runnable updater = () -> { // a twist not to updateUI twice: here, and in DarculaInstaller // double updateUI shall be avoided and causes NPE in some components (HelpView) Ref<Boolean> updated = Ref.create(false); Disposable disposable = Disposer.newDisposable(); ApplicationManager.getApplication().getMessageBus().connect(disposable) .subscribe(LafManagerListener.TOPIC, source -> updated.set(true)); try { if (StartupUiUtil.isUnderDarcula()) { DarculaInstaller.install(); } else if (wasDarcula) { DarculaInstaller.uninstall(); } } finally { Disposer.dispose(disposable); if (!updated.get()) { lafManager.updateUI(); } if (animator != null) { animator.hideSnapshotWithAnimation(); } } }; if (async) { SwingUtilities.invokeLater(updater); } else { updater.run(); } }