diff --git a/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java b/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java
index 84162fffbe10..0ec64a0a9704 100644
--- a/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java
+++ b/java/idea-ui/gen/com/intellij/java/ui/icons/JavaUIIcons.java
@@ -16,4 +16,5 @@ public final class JavaUIIcons {
}
/** 16x16 */ public static final @NotNull Icon IdeaUltimatePromoSmall = load("icons/idea-ultimate-promo-small.svg", -1976155593, 0);
/** 40x40 */ public static final @NotNull Icon IdeaUltimatePromo = load("icons/idea-ultimate-promo.svg", -28146501, 0);
+ /** 16x16 */ public static final @NotNull Icon SpringPromo = load("icons/spring-promo.svg", -1690195316, 0);
}
diff --git a/java/idea-ui/resources/JavaUIIconsMapping.json b/java/idea-ui/resources/JavaUIIconsMapping.json
new file mode 100644
index 000000000000..9be25952cbb4
--- /dev/null
+++ b/java/idea-ui/resources/JavaUIIconsMapping.json
@@ -0,0 +1,7 @@
+{
+ "icons": {
+ "newui": {
+ "spring-promo.svg": "icons/spring-promo.svg"
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/idea-ui/resources/icons/newui/icon-robots.txt b/java/idea-ui/resources/icons/newui/icon-robots.txt
new file mode 100644
index 000000000000..f21601437b7f
--- /dev/null
+++ b/java/idea-ui/resources/icons/newui/icon-robots.txt
@@ -0,0 +1 @@
+skip: *
\ No newline at end of file
diff --git a/java/idea-ui/resources/icons/newui/spring-promo.svg b/java/idea-ui/resources/icons/newui/spring-promo.svg
new file mode 100644
index 000000000000..3720dbba641d
--- /dev/null
+++ b/java/idea-ui/resources/icons/newui/spring-promo.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/java/idea-ui/resources/icons/newui/spring-promo_dark.svg b/java/idea-ui/resources/icons/newui/spring-promo_dark.svg
new file mode 100644
index 000000000000..dd6f33231b14
--- /dev/null
+++ b/java/idea-ui/resources/icons/newui/spring-promo_dark.svg
@@ -0,0 +1,4 @@
+
diff --git a/java/idea-ui/resources/icons/spring-promo.svg b/java/idea-ui/resources/icons/spring-promo.svg
new file mode 100644
index 000000000000..b311081854eb
--- /dev/null
+++ b/java/idea-ui/resources/icons/spring-promo.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/java/idea-ui/resources/messages/JavaUiBundle.properties b/java/idea-ui/resources/messages/JavaUiBundle.properties
index 40abc7d10f10..ddf0e41f92fa 100644
--- a/java/idea-ui/resources/messages/JavaUiBundle.properties
+++ b/java/idea-ui/resources/messages/JavaUiBundle.properties
@@ -711,4 +711,11 @@ action.PromoEndpoints.text=Endpoints
action.PromoDatabase.text=Database
action.PromoKubernetes.text=Kubernetes
action.PromoPersistence.text=Persistence
-action.PromoProfiler.text=IntelliJ Profiler
\ No newline at end of file
+action.PromoProfiler.text=IntelliJ Profiler
+
+feature.spring.wizard.description=Spring Boot integration is available in IntelliJ IDEA Ultimate
+feature.spring.description.html=Use a rich set of built-in developer tools and support for the Spring framework in both Java and Kotlin code, including Spring MVC, Spring Data, Spring Security, and Spring Cloud:
+feature.spring.run.config=Dedicated run configuration
+feature.spring.config.files=Rich configuration files support
+feature.spring.data=JPA and SQL code assistance
+feature.spring.navigation=Advanced navigation and visualization
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
index 8c20973ca7bd..e25b635f0749 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
@@ -3,6 +3,7 @@ package com.intellij.ide.projectWizard;
import com.intellij.diagnostic.PluginException;
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.JavaUiBundle;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.frameworkSupport.FrameworkRole;
@@ -554,8 +555,9 @@ public final class ProjectTypeStep extends ModuleWizardStep implements SettingsS
myContext.setProjectBuilder(builder);
step.updateStep();
+
JComponent component = step.getComponent();
- if (isNewWizard()) {
+ if (isNewWizard() && !(builder instanceof PromoModuleBuilder)) {
component = new JBScrollPane(component);
component.setBorder(JBUI.Borders.empty());
}
@@ -932,6 +934,17 @@ public final class ProjectTypeStep extends ModuleWizardStep implements SettingsS
});
}
+ @Override
+ public Component getListCellRendererComponent(JList extends TemplatesGroup> list,
+ TemplatesGroup value,
+ int index,
+ boolean isSelected,
+ boolean cellHasFocus) {
+ Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ myNextStepLabel.setIcon(value.isPromo() ? AllIcons.Ultimate.Lock : null);
+ return component;
+ }
+
@Override
protected JComponent createItemComponent() {
JComponent component = super.createItemComponent();
diff --git a/java/idea-ui/src/com/intellij/ide/ultimatepromo/PromoSpringModuleBuilder.kt b/java/idea-ui/src/com/intellij/ide/ultimatepromo/PromoSpringModuleBuilder.kt
new file mode 100644
index 000000000000..c06a60709353
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/ultimatepromo/PromoSpringModuleBuilder.kt
@@ -0,0 +1,78 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.ide.ultimatepromo
+
+import com.intellij.icons.AllIcons
+import com.intellij.ide.JavaUiBundle
+import com.intellij.ide.util.projectWizard.*
+import com.intellij.ide.wizard.withVisualPadding
+import com.intellij.java.ui.icons.JavaUIIcons
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.extensions.PluginId
+import com.intellij.openapi.module.ModuleType
+import com.intellij.openapi.module.StdModuleTypes
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.*
+import com.intellij.openapi.util.NlsSafe
+import javax.swing.Icon
+import javax.swing.JComponent
+
+@NlsSafe
+private const val SPRING_NAME = "Spring"
+private const val SPRING_PLUGIN_ID = "com.intellij.spring"
+
+internal class PromoSpringModuleBuilder: ModuleBuilder(), PromoModuleBuilder {
+ override fun getModuleType(): ModuleType<*> = StdModuleTypes.JAVA
+ override fun getWeight(): Int = JVM_WEIGHT
+
+ override fun getBuilderId(): String = "promo-spring"
+ override fun getNodeIcon(): Icon = JavaUIIcons.SpringPromo
+ override fun getPresentableName(): String = SPRING_NAME
+ override fun getDescription(): String = JavaUiBundle.message("feature.spring.wizard.description")
+
+ override fun modifyProjectTypeStep(settingsStep: SettingsStep): ModuleWizardStep? = null
+
+ override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?): ModuleWizardStep {
+ return object : ModuleWizardStep() {
+ private val panel: JComponent = PromoPages.build(
+ PromoFeaturePage(
+ JavaUIIcons.IdeaUltimatePromo,
+ PluginAdvertiserService.ideaUltimate,
+ JavaUiBundle.message("feature.spring.description.html"),
+ listOf(
+ PromoFeatureListItem(
+ AllIcons.RunConfigurations.Application,
+ JavaUiBundle.message("feature.spring.run.config")
+ ),
+ PromoFeatureListItem(
+ AllIcons.FileTypes.Properties,
+ JavaUiBundle.message("feature.spring.config.files")
+ ),
+ PromoFeatureListItem(
+ AllIcons.Nodes.DataTables,
+ JavaUiBundle.message("feature.spring.data")
+ ),
+ PromoFeatureListItem(
+ AllIcons.FileTypes.Diagram,
+ JavaUiBundle.message("feature.spring.navigation")
+ )
+ ),
+ FeaturePromoBundle.message("free.trial.hint"),
+ SPRING_PLUGIN_ID
+ ),
+ FUSEventSource.NEW_PROJECT_WIZARD
+ ).withVisualPadding()
+
+ override fun updateDataModel(): Unit = Unit
+ override fun getComponent(): JComponent = panel
+ override fun validate(): Boolean {
+ FUSEventSource.NEW_PROJECT_WIZARD.openDownloadPageAndLog(null, PluginAdvertiserService.ideaUltimate.downloadUrl,
+ PluginId.getId(SPRING_PLUGIN_ID))
+
+ return false
+ }
+
+ override fun updateStep() {
+ FUSEventSource.NEW_PROJECT_WIZARD.logPluginSuggested(null, PluginId.getId(SPRING_PLUGIN_ID))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java
index 482ee9fb6ba8..411643da61bc 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/TemplatesGroup.java
@@ -3,6 +3,7 @@ package com.intellij.ide.util.newProjectWizard;
import com.intellij.ide.projectWizard.ProjectCategory;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
+import com.intellij.ide.util.projectWizard.PromoModuleBuilder;
import com.intellij.internal.statistic.utils.PluginInfo;
import com.intellij.internal.statistic.utils.PluginInfoDetectorKt;
import com.intellij.openapi.util.Comparing;
@@ -121,4 +122,8 @@ public final class TemplatesGroup implements Comparable {
public void setPluginInfo(PluginInfo pluginInfo) {
myPluginInfo = pluginInfo;
}
+
+ public boolean isPromo() {
+ return myModuleBuilder instanceof PromoModuleBuilder;
+ }
}
diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml
index 8ab8d0674528..1f7ea6f7c4a4 100644
--- a/java/java-impl/src/META-INF/JavaPlugin.xml
+++ b/java/java-impl/src/META-INF/JavaPlugin.xml
@@ -2449,6 +2449,8 @@
+
+
diff --git a/java/java-impl/src/META-INF/community-integration.xml b/java/java-impl/src/META-INF/community-integration.xml
index ea61da89cb40..cdc616f6e275 100644
--- a/java/java-impl/src/META-INF/community-integration.xml
+++ b/java/java-impl/src/META-INF/community-integration.xml
@@ -7,6 +7,8 @@
provider="com.intellij.ide.ultimatepromo.PromoDatabaseConfigurableProvider"
bundle="messages.FeaturePromoBundle"
key="promo.configurable.database"/>
+
+
diff --git a/platform/icons/src/PlatformIconMappings.json b/platform/icons/src/PlatformIconMappings.json
index ad1eef3a096c..889da5370130 100644
--- a/platform/icons/src/PlatformIconMappings.json
+++ b/platform/icons/src/PlatformIconMappings.json
@@ -823,6 +823,9 @@
"createNewProjectTab.svg": "welcome/createNewProjectTab.svg",
"fromVCSTab.svg": "welcome/fromVCSTab.svg",
"open.svg": "welcome/open.svg"
+ },
+ "ultimate": {
+ "lock.svg": "ultimate/lock.svg"
}
}
}
\ No newline at end of file
diff --git a/platform/icons/src/expui/ultimate/lock.svg b/platform/icons/src/expui/ultimate/lock.svg
new file mode 100644
index 000000000000..b490a3af6f08
--- /dev/null
+++ b/platform/icons/src/expui/ultimate/lock.svg
@@ -0,0 +1,11 @@
+
diff --git a/platform/icons/src/expui/ultimate/lock_dark.svg b/platform/icons/src/expui/ultimate/lock_dark.svg
new file mode 100644
index 000000000000..ca289eb723f3
--- /dev/null
+++ b/platform/icons/src/expui/ultimate/lock_dark.svg
@@ -0,0 +1,11 @@
+
diff --git a/platform/icons/src/ultimate/lock.svg b/platform/icons/src/ultimate/lock.svg
index b490a3af6f08..fa17e7ef987a 100644
--- a/platform/icons/src/ultimate/lock.svg
+++ b/platform/icons/src/ultimate/lock.svg
@@ -1,11 +1,7 @@
-