IDEA-268767 New JavaFX project wizard

GitOrigin-RevId: 122ff5370e645d129f777f4319cbe32780675f57
This commit is contained in:
Yuriy Artamonov
2021-05-12 21:27:23 +00:00
committed by intellij-monorepo-bot
parent ccbda8b209
commit 836bff08bd
29 changed files with 1097 additions and 60 deletions
@@ -1,5 +1,6 @@
package com.intellij.ide.starters.local
import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.vfs.VirtualFile
internal class GeneratorContext(
@@ -9,6 +10,8 @@ internal class GeneratorContext(
val artifact: String,
val version: String,
val testRunnerId: String?,
val rootPackage: String,
val sdkVersion: JavaSdkVersion?,
private val languageId: String,
private val libraryIds: Set<String>,
private val dependencyConfig: DependencyConfig,
@@ -47,7 +50,22 @@ internal class GeneratorContext(
/**
* Renders propertyId as ${propertyId}.
*/
fun asPlaceholder(propertyId: String) : String {
fun asPlaceholder(propertyId: String): String {
return "\${$propertyId}"
}
fun isSdkAtLeast(version: String): Boolean {
val desiredSdkVersion = JavaSdkVersion.fromVersionString(version)
return desiredSdkVersion != null && sdkVersion != null && sdkVersion.isAtLeast(desiredSdkVersion)
}
val rootPackagePath: String
get() {
return rootPackage.replace(".", "/").removeSuffix("/")
}
val sdkFeatureVersion: Int
get() {
return sdkVersion?.maxLanguageLevel?.toJavaVersion()?.feature ?: 0
}
}
@@ -25,9 +25,13 @@ import com.intellij.openapi.module.ModuleType
import com.intellij.openapi.module.StdModuleTypes
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.rootManager
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.JavaSdkType
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.SdkTypeId
import com.intellij.openapi.roots.ContentEntry
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ui.configuration.ModulesProvider
import com.intellij.openapi.roots.ui.configuration.setupNewModuleJdk
import com.intellij.openapi.startup.StartupManager
@@ -37,6 +41,7 @@ import com.intellij.openapi.vfs.VfsUtil
import com.intellij.pom.java.LanguageLevel
import com.intellij.ui.GuiUtils
import com.intellij.util.lang.JavaVersion
import org.jetbrains.annotations.Nullable
import java.io.IOException
import java.net.URL
import javax.swing.Icon
@@ -46,6 +51,7 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
companion object {
@JvmStatic
private val VALID_PACKAGE_NAME_PATTERN: Regex = Regex("[^a-zA-Z0-9_.]")
@JvmStatic
private val IMPORTER_EP_NAME: ExtensionPointName<StarterModuleImporter> =
ExtensionPointName.create("com.intellij.starter.moduleImporter")
@@ -106,13 +112,13 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
abstract override fun getPresentableName(): String
abstract override fun getDescription(): String
protected abstract fun getProjectTypes() : List<StarterProjectType>
protected abstract fun getProjectTypes(): List<StarterProjectType>
protected abstract fun getLanguages(): List<StarterLanguage>
protected abstract fun getStarterPack(): StarterPack
protected abstract fun getTestFrameworks(): List<StarterTestRunner>
protected abstract fun getAssets(starter: Starter): List<GeneratorAsset>
protected open fun isExampleCodeProvided(): Boolean = false
protected open fun getMinJavaVersion() : JavaVersion? = LanguageLevel.JDK_1_8.toJavaVersion()
protected open fun getMinJavaVersion(): JavaVersion? = LanguageLevel.JDK_1_8.toJavaVersion()
protected open fun getCustomizedMessages(): CustomizedMessages? = null
@@ -148,7 +154,7 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
startGenerator(module)
}
private fun createSettings() : StarterWizardSettings {
private fun createSettings(): StarterWizardSettings {
return StarterWizardSettings(
getProjectTypes(),
getLanguages(),
@@ -174,7 +180,9 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
}
override fun createWizardSteps(context: WizardContext, modulesProvider: ModulesProvider): Array<ModuleWizardStep> {
return arrayOf(createLibrariesStep(StarterContextProvider(this, context.disposable, starterContext, context, starterSettings, ::getStarterPack)))
return arrayOf(createLibrariesStep(
StarterContextProvider(this, context.disposable, starterContext, context, starterSettings, ::getStarterPack)
))
}
protected open fun createOptionsStep(contextProvider: StarterContextProvider): StarterInitialStep {
@@ -189,7 +197,7 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
return listOf(ProjectSettingsStep::class.java)
}
internal fun getMinJavaVersionInternal() : JavaVersion? = getMinJavaVersion()
internal fun getMinJavaVersionInternal(): JavaVersion? = getMinJavaVersion()
override fun setupRootModel(modifiableRootModel: ModifiableRootModel) {
setupNewModuleJdk(modifiableRootModel, moduleJdk, starterContext.isCreatingNewProject)
@@ -197,10 +205,22 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
}
private fun startGenerator(module: Module) {
val moduleContentRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(contentEntryPath!!.replace("\\", "/"))
?: throw IllegalStateException("Module root not found")
val moduleContentRoot =
if (!ApplicationManager.getApplication().isUnitTestMode) {
LocalFileSystem.getInstance().refreshAndFindFileByPath(contentEntryPath!!.replace("\\", "/"))
?: throw IllegalStateException("Module root not found")
}
else {
val contentEntries = ModuleRootManager.getInstance(module).contentEntries
contentEntries.first { it.sourceFolders.isNotEmpty() }.file!!
}
val starter = starterContext.starter ?: throw IllegalStateException("Starter is not set")
val dependencyConfig = starterContext.starterDependencyConfig ?: error("Starter dependency config is not set")
val sdk = ModuleRootManager.getInstance(module).sdk
val rootPackage = getPackageName(starterContext.group, starterContext.artifact)
val generatorContext = GeneratorContext(
starter.id,
module.name,
@@ -208,47 +228,65 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
starterContext.artifact,
starterContext.version,
starterContext.testFramework!!.id,
rootPackage,
sdk?.let { JavaSdk.getInstance().getVersion(it) },
starterContext.language.id,
starterContext.libraryIds,
starterContext.starterDependencyConfig ?: error("Starter dependency config is not set"),
getGeneratorContextProperties(),
dependencyConfig,
getGeneratorContextProperties(sdk, dependencyConfig),
getAssets(starter),
moduleContentRoot
)
ProgressManager.getInstance().runProcessWithProgressSynchronously(
{
WriteAction.runAndWait<Throwable> {
try {
AssetsProcessor().generateSources(generatorContext, getTemplateProperties())
}
catch (e: IOException) {
logger<StarterModuleBuilder>().error("Unable to create module by template", e)
ApplicationManager.getApplication().invokeLater {
Messages.showErrorDialog(
JavaStartersBundle.message("starter.generation.error", e.message ?: ""),
presentableName)
if (!ApplicationManager.getApplication().isUnitTestMode) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(
{
WriteAction.runAndWait<Throwable> {
try {
AssetsProcessor().generateSources(generatorContext, getTemplateProperties())
}
catch (e: IOException) {
logger<StarterModuleBuilder>().error("Unable to create module by template", e)
ApplicationManager.getApplication().invokeLater {
Messages.showErrorDialog(
JavaStartersBundle.message("starter.generation.error", e.message ?: ""),
presentableName)
}
}
applyAdditionalChanges(module)
}
},
JavaStartersBundle.message("starter.generation.progress", presentableName),
true, module.project)
applyAdditionalChanges(module)
}
},
JavaStartersBundle.message("starter.generation.progress", presentableName),
true, module.project)
StartupManager.getInstance(module.project).runAfterOpened { // IDEA-244863
GuiUtils.invokeLaterIfNeeded(Runnable {
if (module.isDisposed) return@Runnable
StartupManager.getInstance(module.project).runAfterOpened { // IDEA-244863
GuiUtils.invokeLaterIfNeeded(Runnable {
if (module.isDisposed) return@Runnable
ReformatCodeProcessor(module.project, module, false).run()
// import of module may dispose it and create another, open files first
openSampleFiles(module, getFilePathsToOpen())
ReformatCodeProcessor(module.project, module, false).run()
// import of module may dispose it and create another, open files first
openSampleFiles(module, getFilePathsToOpen())
importModule(module)
}, ModalityState.NON_MODAL, module.disposed)
importModule(module)
}, ModalityState.NON_MODAL, module.disposed)
}
}
else {
// test mode, open files immediately, do not import module
AssetsProcessor().generateSources(generatorContext, getTemplateProperties())
ReformatCodeProcessor(module.project, module, false).run()
openSampleFiles(module, getFilePathsToOpen())
}
}
override fun doAddContentEntry(modifiableRootModel: ModifiableRootModel): ContentEntry? {
if (ApplicationManager.getApplication().isUnitTestMode) {
// do not create new content entry
return modifiableRootModel.contentEntries.first { it.sourceFolders.isNotEmpty() }
}
return super.doAddContentEntry(modifiableRootModel)
}
open fun getTemplateProperties(): Map<String, Any> = emptyMap()
@@ -261,9 +299,8 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
return javaClass.getResource(resourcePath) ?: error("Failed to get resource: $resourcePath")
}
protected open fun getGeneratorContextProperties(): Map<String, String> {
val packageName = getPackageName(starterContext.group, starterContext.artifact)
return mapOf("rootPackage" to packageName)
protected open fun getGeneratorContextProperties(sdk: @Nullable Sdk?, dependencyConfig: DependencyConfig): Map<String, String> {
return emptyMap()
}
protected fun getSamplesExt(language: StarterLanguage): String {
@@ -274,4 +311,9 @@ abstract class StarterModuleBuilder : ModuleBuilder() {
else -> throw UnsupportedOperationException()
}
}
protected fun getPackagePath(group: String, artifact: String): String {
val packageName = getPackageName(group, artifact)
return packageName.replace(".", "/").removeSuffix("/")
}
}
@@ -4,6 +4,7 @@ package com.intellij.ide.starters.local
import com.intellij.openapi.util.Version
import org.jdom.Element
import org.jetbrains.annotations.ApiStatus
import java.io.File
import java.io.IOException
import java.nio.file.Files
@@ -12,13 +13,13 @@ import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
internal object StarterUtils {
@ApiStatus.Internal
object StarterUtils {
private val PLACEHOLDER_VERSION_PATTERN: Regex = Regex("\\$\\{(.+)}")
private class IncorrectBomFileException(message: String) : IOException(message)
internal fun parseDependencyConfig(projectTag: Element, resourcePath: String, interpolateProperties: Boolean = true): DependencyConfig {
fun parseDependencyConfig(projectTag: Element, resourcePath: String, interpolateProperties: Boolean = true): DependencyConfig {
val properties: MutableMap<String, String> = mutableMapOf()
val dependencies: MutableList<Dependency> = mutableListOf()
val bomVersion: String
@@ -22,7 +22,7 @@ internal class AssetsProcessor {
else
""
val outputDirectory = VfsUtil.createDirectoryIfMissing(context.outputDirectory.path)
val outputDirectory = VfsUtil.createDirectoryIfMissing(context.outputDirectory.fileSystem, context.outputDirectory.path)
?: throw IllegalStateException("Unable to create directory ${context.outputDirectory.path}")
if (asset is GeneratorEmptyDirectory) {
@@ -7,6 +7,7 @@ import com.intellij.ide.starters.JavaStartersBundle
import com.intellij.ide.util.PropertiesComponent
import com.intellij.ide.util.projectWizard.ModuleBuilder
import com.intellij.ide.util.projectWizard.ProjectWizardUtil
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.module.ModuleType
import com.intellij.openapi.module.StdModuleTypes
import com.intellij.openapi.observable.properties.GraphProperty
@@ -103,6 +104,11 @@ fun validateJavaVersion(sdkProperty: GraphProperty<Sdk?>, javaVersion: String?):
}
fun setupNewModuleJdk(modifiableRootModel: ModifiableRootModel, selectedJdk: Sdk?, isCreatingNewProject: Boolean): Sdk? {
if (ApplicationManager.getApplication().isUnitTestMode && selectedJdk == modifiableRootModel.sdk) {
// do not change SDK in tests
return selectedJdk
}
val sdk = selectedJdk ?: getProjectJdk(modifiableRootModel.project)
if (sdk != null) {
if (isCreatingNewProject || (!isCreatingNewProject && sdk == getProjectJdk(modifiableRootModel.project))) {
+1
View File
@@ -34,5 +34,6 @@
<orderEntry type="module" module-name="intellij.properties.psi.impl" />
<orderEntry type="module" module-name="intellij.platform.codeStyle.impl" />
<orderEntry type="module" module-name="intellij.platform.ide.util.io" />
<orderEntry type="module" module-name="intellij.spellchecker" />
</component>
</module>
@@ -3,17 +3,16 @@
<id>org.jetbrains.plugins.javaFX</id>
<vendor>JetBrains</vendor>
<category>JVM Frameworks</category>
<description>
<![CDATA[
Enables <a href="http://www.oracle.com/technetwork/java/javafx/overview/index.html">JavaFX</a> support.
The following features are available:
<ul>
<li>Dedicated file type.</li>
<li>Ability to create a project with the special file and directory structure.</li>
<li>JavaFX-aware coding assistance (code completion, search, navigation and refactoring in JavaFX-specific source files).</li>
<li>Integration with <a href="http://www.oracle.com/technetwork/java/javafx/tools/index.html">JavaFX Scene Builder</a>.</li>
</ul>
]]>
</description>
<description><![CDATA[
Enables <a href="https://openjfx.io/">JavaFX</a> support.
The following features are available:
<ul>
<li>Dedicated FXML file type.</li>
<li>Ability to create a project with the special file and directory structure.</li>
<li>JavaFX-aware coding assistance (code completion, search, navigation and refactoring in JavaFX-specific source files).</li>
<li>Integration with <a href="https://github.com/gluonhq/scenebuilder/wiki/Basic-JavaFX-project-with-Scene-Builder">JavaFX Scene Builder</a>.</li>
</ul>
]]></description>
<xi:include href="/META-INF/common-javaFX-plugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
</idea-plugin>
@@ -0,0 +1,9 @@
bootstrapfx
dlsc
formsfx
hansolo
ikonli
javafxplugin
kordamp
synedra
tilesfx
@@ -0,0 +1,24 @@
package ${context.rootPackage}
import groovy.transform.CompileStatic
import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.stage.Stage
@CompileStatic
class HelloApplication extends Application {
@Override
void start(Stage stage) {
def fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"))
def scene = new Scene(fxmlLoader.load() as Parent, 320, 240)
stage.setTitle("Hello!")
stage.setScene(scene)
stage.show()
}
static void main(String[] args) {
launch(HelloApplication)
}
}
@@ -0,0 +1,23 @@
package ${context.rootPackage};
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
@@ -0,0 +1,20 @@
package ${context.rootPackage}
import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.Scene
import javafx.stage.Stage
class HelloApplication : Application() {
override fun start(stage: Stage) {
val fxmlLoader = FXMLLoader(HelloApplication::class.java.getResource("hello-view.fxml"))
val scene = Scene(fxmlLoader.load(), 320.0, 240.0)
stage.title = "Hello!"
stage.scene = scene
stage.show()
}
}
fun main() {
Application.launch(HelloApplication::class.java)
}
@@ -0,0 +1,14 @@
package ${context.rootPackage}
import javafx.fxml.FXML
import javafx.scene.control.Label
class HelloController {
@FXML
private Label welcomeText
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!")
}
}
@@ -0,0 +1,14 @@
package ${context.rootPackage};
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
}
@@ -0,0 +1,14 @@
package ${context.rootPackage}
import javafx.fxml.FXML
import javafx.scene.control.Label
class HelloController {
@FXML
private lateinit var welcomeText: Label
@FXML
private fun onHelloButtonClick() {
welcomeText.text = "Welcome to JavaFX Application!"
}
}
@@ -0,0 +1,84 @@
plugins {
id 'java'
id 'application'
#if ($context.hasLanguage("groovy"))
id 'groovy'
#end
#if ($context.hasLanguage("kotlin"))
id 'org.jetbrains.kotlin.jvm' version '${context.getVersion("org.jetbrains.kotlin", "kotlin-gradle-plugin")}'
#end
id 'org.openjfx.javafxplugin' version '${context.getVersion("org.openjfx", "javafxplugin")}'
}
group '${context.group}'
version '${context.version}'
repositories {
mavenCentral()
}
#if ($context.testRunnerId == "junit")
ext {
junitVersion = '${context.getVersion("org.junit.jupiter", "junit-jupiter-engine")}'
}
#end
#if ($context.sdkFeatureVersion > 0)
sourceCompatibility = ${context.sdkFeatureVersion}
targetCompatibility = ${context.sdkFeatureVersion}
#end
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
mainClassName = '${context.rootPackage}.HelloApplication'
#if ($context.hasLanguage("kotlin"))
[compileKotlin, compileTestKotlin].forEach {
it.kotlinOptions {
jvmTarget = '11'
}
}
#end
javafx {
version = '${context.getProperty("javafx.version")}'
modules = ['javafx.controls', 'javafx.fxml'#if ($context.hasLibrary("tilesfx")), 'javafx.web'#end]
}
dependencies {
#if ($context.hasLanguage("groovy"))
implementation('org.codehaus.groovy:groovy:${context.getVersion("org.codehaus.groovy", "groovy")}')
#end
#if ($context.hasLibrary("controlsfx"))
implementation('org.controlsfx:controlsfx:${context.getVersion("org.controlsfx", "controlsfx")}')
#end
#if ($context.hasLibrary("formsfx"))
implementation('com.dlsc.formsfx:formsfx-core:${context.getVersion("com.dlsc.formsfx", "formsfx-core")}')
#end
#if ($context.hasLibrary("validatorfx"))
implementation('net.synedra:validatorfx:${context.getVersion("net.synedra", "validatorfx")}')
#end
#if ($context.hasLibrary("ikonli"))
implementation('org.kordamp.ikonli:ikonli-javafx:${context.getVersion("org.kordamp.ikonli", "ikonli-javafx")}')
#end
#if ($context.hasLibrary("bootstrapfx"))
implementation('org.kordamp.bootstrapfx:bootstrapfx-core:${context.getVersion("org.kordamp.bootstrapfx", "bootstrapfx-core")}')
#end
#if ($context.hasLibrary("tilesfx"))
implementation('eu.hansolo:tilesfx:${context.getVersion("eu.hansolo", "tilesfx")}')
#end
#if ($context.testRunnerId == "junit")
testImplementation("org.junit.jupiter:junit-jupiter-api:${context.asPlaceholder("junitVersion")}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${context.asPlaceholder("junitVersion")}")
#end
#if ($context.testRunnerId == "testng")
testImplementation('org.testng:testng:${context.getVersion("org.testng", "testng")}')
#end
}
test {
#if ($context.testRunnerId == "junit")useJUnitPlatform()#end
#if ($context.testRunnerId == "testng")useTestNG()#end
}
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-${context.getBomProperty("gradle.version")}-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -0,0 +1,17 @@
#set($H = '#')
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="${context.rootPackage}.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello!" onAction="${H}onHelloButtonClick"/>
</VBox>
@@ -0,0 +1,35 @@
module ${context.rootPackage} {
requires javafx.controls;
requires javafx.fxml;
#if ($context.hasLibrary("tilesfx"))
requires javafx.web;
#end
#if ($context.hasLanguage("groovy"))
requires org.codehaus.groovy;
#end
#if ($context.hasLanguage("kotlin"))
requires kotlin.stdlib;
#end
#if ($context.hasLibrary("controlsfx"))
requires org.controlsfx.controls;
#end
#if ($context.hasLibrary("formsfx"))
requires com.dlsc.formsfx;
#end
#if ($context.hasLibrary("validatorfx"))
requires validatorfx;
#end
#if ($context.hasLibrary("ikonli"))
requires org.kordamp.ikonli.javafx;
#end
#if ($context.hasLibrary("bootstrapfx"))
requires org.kordamp.bootstrapfx.core;
#end
#if ($context.hasLibrary("tilesfx"))
requires eu.hansolo.tilesfx;
#end
opens ${context.rootPackage} to javafx.fxml;
exports ${context.rootPackage};
}
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>${context.group}</groupId>
<artifactId>${context.artifact}</artifactId>
<version>${context.version}</version>
<name>${context.moduleName}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>${context.sdkFeatureVersion}</maven.compiler.target>
<maven.compiler.source>${context.sdkFeatureVersion}</maven.compiler.source>
#if ($context.testRunnerId == "junit")<junit.version>${context.getVersion("org.junit.jupiter", "junit-jupiter-api")}</junit.version>#end
#if ($context.hasLanguage("kotlin"))<kotlin.version>${context.getVersion("org.jetbrains.kotlin", "kotlin-maven-plugin")}</kotlin.version>#end
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${context.getProperty("javafx.version")}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${context.getProperty("javafx.version")}</version>
</dependency>
#if ($context.hasLibrary("tilesfx"))<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>${context.getProperty("javafx.version")}</version>
</dependency>#end
#if ($context.hasLibrary("controlsfx"))<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>${context.getVersion("org.controlsfx", "controlsfx")}</version>
</dependency>#end
#if ($context.hasLibrary("formsfx"))<dependency>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx-core</artifactId>
<version>${context.getVersion("com.dlsc.formsfx", "formsfx-core")}</version>
</dependency>#end
#if ($context.hasLibrary("validatorfx"))<dependency>
<groupId>net.synedra</groupId>
<artifactId>validatorfx</artifactId>
<version>${context.getVersion("net.synedra", "validatorfx")}</version>
</dependency>#end
#if ($context.hasLibrary("ikonli"))<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>${context.getVersion("org.kordamp.ikonli", "ikonli-javafx")}</version>
</dependency>#end
#if ($context.hasLibrary("bootstrapfx"))<dependency>
<groupId>org.kordamp.bootstrapfx</groupId>
<artifactId>bootstrapfx-core</artifactId>
<version>${context.getVersion("org.kordamp.bootstrapfx", "bootstrapfx-core")}</version>
</dependency>#end
#if ($context.hasLibrary("tilesfx"))<dependency>
<groupId>eu.hansolo</groupId>
<artifactId>tilesfx</artifactId>
<version>${context.getVersion("eu.hansolo", "tilesfx")}</version>
</dependency>#end
#if ($context.testRunnerId == "junit")<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${context.asPlaceholder("junit.version")}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${context.asPlaceholder("junit.version")}</version>
<scope>test</scope>
</dependency>#end
#if ($context.testRunnerId == "testng")<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${context.getVersion("org.testng", "testng")}</version>
<scope>test</scope>
</dependency>#end
#if ($context.hasLanguage("groovy"))<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>${context.getVersion("org.codehaus.groovy", "groovy")}</version>
</dependency>#end
#if ($context.hasLanguage("kotlin"))<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${context.asPlaceholder("kotlin.version")}</version>
</dependency>#end
</dependencies>
<build>
#if ($context.hasLanguage("kotlin"))
<sourceDirectory>${context.asPlaceholder("project.basedir")}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${context.asPlaceholder("project.basedir")}/src/test/kotlin</testSourceDirectory>
#end
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>${context.getVersion("org.openjfx", "javafx-maven-plugin")}</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>${context.rootPackage}.HelloApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
#if ($context.hasLanguage("groovy"))<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>${context.getVersion("org.codehaus.gmavenplus", "gmavenplus-plugin")}</version>
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>compile</goal>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>#end
#if ($context.hasLanguage("kotlin"))<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${context.asPlaceholder("kotlin.version")}</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>11</jvmTarget>
</configuration>
</plugin>#end
</plugins>
</build>
</project>
@@ -0,0 +1 @@
rootProject.name = "${context.artifact}"
@@ -0,0 +1,2 @@
#* @implicitly included *#
#* @vtlvariable name="context" type="com.intellij.ide.starters.local.GeneratorContext" *#
@@ -134,14 +134,21 @@ dialog.title.choose.preloader.class=Choose Preloader Class
dialog.title.choose.application.class=Choose Application Class
column.name.artifact.manifest.property.name=Name
column.name.artifact.manifest.property.value=Value
java.fx.artifacts.tab.name=Java FX
java.fx.artifacts.tab.name=JavaFX
javafx.preloader.tab.name=JavaFX Preloader
scene.builder.editor.tab.name=Scene Builder
constant.not.found=Constant ''{0}'' is not found
cannot.class.name.to.field.name=Cannot set {0} to field ''{1}''
enum.constant.not.found=No enum constant ''{0}'' in {1}
dialect.display.name=Java FX
group.name.javafx=JavaFX
inspection.java.fx.resource.property.value.display.name=The value from properties file is incompatible with the attribute type
java.version.7.or.higher.is.required.to.build.javafx.package=Java version 7 or higher is required to build JavaFX package
javafx.migration.description=Fix imports of JavaFX API classes according to JEP 253. Note that a few classes are no longer public.
javafx.migration.description=Fix imports of JavaFX API classes according to JEP 253. Note that a few classes are no longer public.
javafx.module.builder.description=Desktop application with <b>JavaFX</b> toolkit.
library.controlsfx.description=High quality UI controls and other tools to complement the core JavaFX distribution.
library.formsfx.description=Enables the developer to create forms with ease and creates well-designed and user-friendly forms by default.
library.validatorfx.description=Validation library for JavaFX inspired by ControlsFX but tries to overcome its shortcomings.
library.ikonli.description=Icon packs that can be used in Java applications.
library.bootstrapfx.description=Provides a CSS stylesheet that closely resembles the Twitter Bootstrap while being custom tailored for JavaFX\u2019s unique CSS flavor.
library.tilesfx.description=A JavaFX library containing tiles for Dashboards.
@@ -0,0 +1,105 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.intellij</groupId>
<artifactId>javafx-starter</artifactId>
<version>1.0</version>
<properties>
<gradle.version>6.9</gradle.version>
<junit.version>5.7.1</junit.version>
<kotlin.version>1.4.32</kotlin.version>
<jersey.version>2.33</jersey.version>
<!-- OpenJFX release trains -->
<fx.default.version>11.0.2</fx.default.version>
<fx11.version>11.0.2</fx11.version>
<fx12.version>12.0.2</fx12.version>
<fx13.version>13.0.2</fx13.version>
<fx14.version>14.0.2</fx14.version>
<fx15.version>15.0.1</fx15.version>
<fx16.version>16</fx16.version>
<fx17.version>17-ea+9</fx17.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafxplugin</artifactId>
<version>0.0.10</version>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.1.0</version>
</dependency>
<dependency>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx-core</artifactId>
<version>11.4.2</version>
</dependency>
<dependency>
<groupId>net.synedra</groupId>
<artifactId>validatorfx</artifactId>
<version>0.1.13</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>12.2.0</version>
</dependency>
<dependency>
<groupId>org.kordamp.bootstrapfx</groupId>
<artifactId>bootstrapfx-core</artifactId>
<version>0.4.0</version>
</dependency>
<dependency>
<groupId>eu.hansolo</groupId>
<artifactId>tilesfx</artifactId>
<version>11.48</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-gradle-plugin</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.12.1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
@@ -78,7 +78,7 @@
<renameHandler implementation="org.jetbrains.plugins.javaFX.refactoring.JavaFxPropertyRenameHandler"/>
<completion.contributor implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxCompletionContributor" language="XML" order="before xmlNonFirst"/>
<manifest.parser.provider implementation="org.jetbrains.plugins.javaFX.manifest.JavaFxManifestHeaderParsers"/>
<projectTemplate projectType="Java FX" templatePath="resources/projectTemplates/Java/JavaFX Application.zip" category="true"/>
<javaMainMethodProvider implementation="org.jetbrains.plugins.javaFX.JavaFxMainMethodRunConfigurationProvider"/>
<deadCode implementation="org.jetbrains.plugins.javaFX.JavaFxEntryPoint"/>
<cantBeStatic implementation="org.jetbrains.plugins.javaFX.JavaFxCanBeStaticExtension" />
@@ -87,6 +87,11 @@
<postStartupActivity implementation="org.jetbrains.plugins.javaFX.fxml.JavaFxModuleUtil$JavaFxDetectionStartupActivity"/>
<createFromTemplateHandler implementation="org.jetbrains.plugins.javaFX.actions.JavaFxCreateFromTemplateHandler" order="before java"/>
<projectTemplateParameterFactory implementation="org.jetbrains.plugins.javaFX.JavaFXVersionFactory"/>
<moduleBuilder builderClass="org.jetbrains.plugins.javaFX.wizard.JavaFxModuleBuilder"/>
<fileTemplateGroup implementation="org.jetbrains.plugins.javaFX.wizard.JavaFxModuleTemplateGroup"/>
<spellchecker.bundledDictionaryProvider implementation="org.jetbrains.plugins.javaFX.JavaeeBundledDictionaryProvider"/>
</extensions>
<projectListeners>
@@ -2,6 +2,7 @@
package org.jetbrains.plugins.javaFX;
import com.intellij.DynamicBundle;
import com.intellij.openapi.util.NlsSafe;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -13,6 +14,8 @@ public final class JavaFXBundle extends DynamicBundle {
@NonNls private static final String BUNDLE = "messages.JavaFXBundle";
private static final JavaFXBundle INSTANCE = new JavaFXBundle();
public static final @NlsSafe String JAVA_FX = "JavaFX";
private JavaFXBundle() {
super(BUNDLE);
}
@@ -0,0 +1,11 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.javaFX;
import com.intellij.spellchecker.BundledDictionaryProvider;
final class JavaeeBundledDictionaryProvider implements BundledDictionaryProvider {
@Override
public String[] getBundledDictionaries() {
return new String[]{"/dictionaries/javafx.dic"};
}
}
@@ -0,0 +1,155 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.javaFX.wizard
import com.intellij.icons.AllIcons
import com.intellij.ide.fileTemplates.FileTemplateManager
import com.intellij.ide.starters.local.*
import com.intellij.ide.starters.local.gradle.GradleResourcesProvider
import com.intellij.ide.starters.shared.*
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.pom.java.LanguageLevel
import com.intellij.util.lang.JavaVersion
import org.jetbrains.plugins.javaFX.JavaFXBundle
import javax.swing.Icon
internal open class JavaFxModuleBuilder : StarterModuleBuilder() {
override fun getBuilderId(): String = "javafx"
override fun getNodeIcon(): Icon = AllIcons.Nodes.Module
override fun getPresentableName(): String = JavaFXBundle.JAVA_FX
override fun getDescription(): String = JavaFXBundle.message("javafx.module.builder.description")
override fun getWeight(): Int = super.getWeight() + 10
override fun getMinJavaVersion(): JavaVersion = LanguageLevel.JDK_11.toJavaVersion()
override fun isExampleCodeProvided(): Boolean = true
override fun getProjectTypes(): List<StarterProjectType> {
return listOf(MAVEN_PROJECT, GRADLE_PROJECT)
}
override fun getLanguages(): List<StarterLanguage> {
return listOf(
JAVA_STARTER_LANGUAGE,
KOTLIN_STARTER_LANGUAGE,
GROOVY_STARTER_LANGUAGE
)
}
override fun getTestFrameworks(): List<StarterTestRunner> {
return listOf(JUNIT_TEST_RUNNER, TESTNG_TEST_RUNNER)
}
override fun getStarterPack(): StarterPack {
return StarterPack("javafx", listOf(
Starter("javafx", JavaFXBundle.JAVA_FX, getDependencyConfig("/starters/javafx.pom"), listOf(
Library("bootstrapfx", null, "BootstrapFX", JavaFXBundle.message("library.bootstrapfx.description"),
"org.kordamp.bootstrapfx", "bootstrapfx-core", listOf(
LibraryLink(LibraryLinkType.WEBSITE, "https://github.com/kordamp/bootstrapfx")
)),
Library("controlsfx", null, "ControlsFX", JavaFXBundle.message("library.controlsfx.description"),
"org.controlsfx", "controlsfx", listOf(
LibraryLink(LibraryLinkType.WEBSITE, "https://controlsfx.github.io/")
)),
Library("formsfx", null, "FormsFX", JavaFXBundle.message("library.formsfx.description"),
"com.dlsc.formsfx", "formsfx-core", listOf(
LibraryLink(LibraryLinkType.WEBSITE, "https://github.com/dlsc-software-consulting-gmbh/FormsFX/")
)),
Library("ikonli", null, "Ikonli", JavaFXBundle.message("library.ikonli.description"),
"org.kordamp.ikonli", "ikonli-javafx", listOf(
LibraryLink(LibraryLinkType.REFERENCE, "https://kordamp.org/ikonli/")
)),
Library("tilesfx", null, "TilesFX", JavaFXBundle.message("library.tilesfx.description"),
"eu.hansolo", "tilesfx", listOf(
LibraryLink(LibraryLinkType.WEBSITE, "https://github.com/HanSolo/tilesfx")
)),
Library("validatorfx", null, "ValidatorFX", JavaFXBundle.message("library.validatorfx.description"),
"net.synedra", "validatorfx", listOf(
LibraryLink(LibraryLinkType.WEBSITE, "https://github.com/effad/ValidatorFX")
))
))
))
}
override fun getFilePathsToOpen(): List<String> {
val files = mutableListOf<String>()
if (starterContext.projectType == MAVEN_PROJECT) {
files.add("pom.xml")
}
else if (starterContext.projectType == GRADLE_PROJECT) {
files.add("build.gradle")
}
val packagePath = getPackagePath(starterContext.group, starterContext.artifact)
val samplesLanguage = starterContext.language.id
val samplesExt = getSamplesExt(starterContext.language)
files.add("src/main/resources/${packagePath}/hello-view.fxml")
files.add("src/main/${samplesLanguage}/${packagePath}/HelloController.${samplesExt}")
files.add("src/main/${samplesLanguage}/${packagePath}/HelloApplication.${samplesExt}")
return files
}
override fun getGeneratorContextProperties(sdk: Sdk?, dependencyConfig: DependencyConfig): Map<String, String> {
val properties = HashMap(super.getGeneratorContextProperties(sdk, dependencyConfig))
val sdkVersion = sdk?.let { JavaSdk.getInstance().getVersion(it) }
val sdkFeatureVersion = sdkVersion?.maxLanguageLevel?.toJavaVersion()?.feature
if (sdkFeatureVersion == null) {
properties["javafx.version"] = getUnknownFxVersion(dependencyConfig)
}
else {
val targetVersion = dependencyConfig.properties["fx${sdkFeatureVersion}.version"]
properties["javafx.version"] = targetVersion ?: getUnknownFxVersion(dependencyConfig)
}
return properties
}
private fun getUnknownFxVersion(dependencyConfig: DependencyConfig): String? {
return dependencyConfig.properties["fx.default.version"]
}
override fun getAssets(starter: Starter): List<GeneratorAsset> {
val ftManager = FileTemplateManager.getInstance(ProjectManager.getInstance().defaultProject)
val assets = mutableListOf<GeneratorAsset>()
if (starterContext.projectType == GRADLE_PROJECT) {
assets.add(GeneratorTemplateFile("build.gradle", ftManager.getJ2eeTemplate(JavaFxModuleTemplateGroup.JAVAFX_BUILD_GRADLE)))
assets.add(GeneratorTemplateFile("settings.gradle", ftManager.getJ2eeTemplate(JavaFxModuleTemplateGroup.JAVAFX_SETTINGS_GRADLE)))
assets.add(GeneratorTemplateFile("gradle/wrapper/gradle-wrapper.properties",
ftManager.getJ2eeTemplate(JavaFxModuleTemplateGroup.JAVAFX_GRADLEW_PROPERTIES)))
assets.addAll(GradleResourcesProvider().getGradlewResources())
}
else if (starterContext.projectType == MAVEN_PROJECT) {
assets.add(GeneratorTemplateFile("pom.xml", ftManager.getJ2eeTemplate(JavaFxModuleTemplateGroup.JAVAFX_POM_XML)))
}
val packagePath = getPackagePath(starterContext.group, starterContext.artifact)
val samplesLanguage = starterContext.language.id
val samplesExt = getSamplesExt(starterContext.language)
assets.add(GeneratorTemplateFile("src/main/${samplesLanguage}/module-info.java",
ftManager.getJ2eeTemplate(JavaFxModuleTemplateGroup.JAVAFX_MODULE_INFO_JAVA)))
if (starterContext.includeExamples) {
assets.add(GeneratorTemplateFile("src/main/${samplesLanguage}/${packagePath}/HelloApplication.${samplesExt}",
ftManager.getJ2eeTemplate("javafx-HelloApplication-${samplesLanguage}.${samplesExt}")))
assets.add(GeneratorTemplateFile("src/main/${samplesLanguage}/${packagePath}/HelloController.${samplesExt}",
ftManager.getJ2eeTemplate("javafx-HelloController-${samplesLanguage}.${samplesExt}")))
assets.add(GeneratorTemplateFile("src/main/resources/${packagePath}/hello-view.fxml",
ftManager.getJ2eeTemplate(JavaFxModuleTemplateGroup.JAVAFX_HELLO_VIEW_FXML)))
}
else {
assets.add(GeneratorEmptyDirectory("src/main/${samplesLanguage}/${packagePath}"))
assets.add(GeneratorEmptyDirectory("src/main/resources/${packagePath}"))
}
assets.add(GeneratorEmptyDirectory("src/test/${samplesLanguage}/${packagePath}"))
return assets
}
}
@@ -0,0 +1,40 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.javaFX.wizard
import com.intellij.icons.AllIcons
import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor
import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory
import org.jetbrains.plugins.javaFX.JavaFXBundle
internal class JavaFxModuleTemplateGroup : FileTemplateGroupDescriptorFactory {
override fun getFileTemplatesDescriptor(): FileTemplateGroupDescriptor {
val root = FileTemplateGroupDescriptor(JavaFXBundle.JAVA_FX, AllIcons.Nodes.Module)
root.addTemplate(JAVAFX_POM_XML)
root.addTemplate(JAVAFX_BUILD_GRADLE)
root.addTemplate(JAVAFX_SETTINGS_GRADLE)
root.addTemplate(JAVAFX_GRADLEW_PROPERTIES)
root.addTemplate(JAVAFX_HELLO_VIEW_FXML)
root.addTemplate(JAVAFX_MODULE_INFO_JAVA)
root.addTemplate("javafx-HelloApplication-java.java")
root.addTemplate("javafx-HelloApplication-kotlin.kt")
root.addTemplate("javafx-HelloApplication-groovy.groovy")
root.addTemplate("javafx-HelloController-java.java")
root.addTemplate("javafx-HelloController-kotlin.kt")
root.addTemplate("javafx-HelloController-groovy.groovy")
return root
}
companion object {
const val JAVAFX_BUILD_GRADLE = "javafx-build.gradle"
const val JAVAFX_POM_XML = "javafx-pom.xml"
const val JAVAFX_SETTINGS_GRADLE = "javafx-settings.gradle"
const val JAVAFX_GRADLEW_PROPERTIES = "javafx-gradle-wrapper.properties"
const val JAVAFX_HELLO_VIEW_FXML = "javafx-hello-view.fxml"
const val JAVAFX_MODULE_INFO_JAVA = "javafx-module-info.java"
}
}
@@ -0,0 +1,224 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.javaFX
import com.intellij.ide.starters.local.DependencyConfig
import com.intellij.ide.starters.local.Starter
import com.intellij.ide.starters.local.StarterContext
import com.intellij.ide.starters.local.StarterUtils
import com.intellij.ide.starters.shared.*
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.util.JDOMUtil
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_11
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase4
import org.jetbrains.plugins.javaFX.wizard.JavaFxModuleBuilder
import org.junit.Test
class JavaFxModuleBuilderTest : LightJavaCodeInsightFixtureTestCase4(JAVA_11) {
@Test
fun emptyMavenProject() {
val builder = TestModuleBuilder(fixture.module).withStarterContext {
language = JAVA_STARTER_LANGUAGE
projectType = MAVEN_PROJECT
testFramework = JUNIT_TEST_RUNNER
isCreatingNewProject = true
}
builder.setupModule()
expectFile("src/main/java/com/example/demo/HelloApplication.java", """
package com.example.demo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
""".trimIndent())
val dlr = "\$"
expectFile("pom.xml", """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>light_idea_test_case</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<junit.version>${dlr}{junit.version}</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${dlr}{junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${dlr}{junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.demo.HelloApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
""".trimIndent())
}
@Test
fun emptyGradleProject() {
val builder = TestModuleBuilder(fixture.module).withStarterContext {
language = JAVA_STARTER_LANGUAGE
projectType = GRADLE_PROJECT
testFramework = TESTNG_TEST_RUNNER
isCreatingNewProject = true
}
builder.setupModule()
expectFile("src/main/java/com/example/demo/HelloController.java", """
package com.example.demo;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
}
""".trimIndent())
expectFile("build.gradle", """
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.10'
}
group 'com.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
sourceCompatibility = 11
targetCompatibility = 11
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
mainClassName = 'com.example.demo.HelloApplication'
javafx {
version = '11.0.2'
modules = ['javafx.controls', 'javafx.fxml']
}
dependencies {
testImplementation('org.testng:testng:7.1.0')
}
test {
useTestNG()
}
""".trimIndent())
expectFile("settings.gradle", """
rootProject.name = "demo"
""".trimIndent())
}
private fun expectFile(path: String, content: String) {
fixture.configureFromTempProjectFile(path)
fixture.checkResult(content)
}
private class TestModuleBuilder(private val module: Module) : JavaFxModuleBuilder() {
init {
starterContext.starterPack = getStarterPack()
moduleJdk = ModuleRootManager.getInstance(module).sdk
starterContext.starter = starterContext.starterPack.starters.first()
starterContext.starterDependencyConfig = loadDependencyConfig(starterContext.starter!!)
}
private fun loadDependencyConfig(starter: Starter): DependencyConfig {
val starterDependencyDom = starter.versionConfigUrl.openStream().use { JDOMUtil.load(it) }
return StarterUtils.parseDependencyConfig(starterDependencyDom, starter.versionConfigUrl.path, false)
}
fun setupModule() {
ApplicationManager.getApplication().invokeAndWait {
runWriteAction {
super.setupModule(module)
}
}
}
fun withStarterContext(consumer: StarterContext.() -> Unit): TestModuleBuilder {
consumer.invoke(starterContext)
return this
}
}
}