Can't use a font in Kotlin Multiplatform - kotlin

Pretty simple; just created a Compose Multiplatform project from the wizard.
Went ahead and created the Theme; but I wanted to use the same font so I put poppins.ttf inside commonMain/resources/font/.
Then I declared the following in commonMain module:
expect val projectFontFamily: FontFamily
On the commonDesktop module I used:
actual val projectFontFamily: FontFamily = FontFamily(
Font("font/poppins.ttf")
)
Great, that worked. Now on commonAndroid:
actual val projectFontFamily: FontFamily = FontFamily(
Font(R.font.poppins)
)
For some reason the R class is not properly being generated and I cannot use R.font.poppins.
If I rename "resources" to "res" and shove the font into res/font/ then it works. (But I just duplicated the font file).
How do I get around doing this?

It turns out it's rather a gradle issue and some inexperience with KMM.
Kotlin multiplatform projects by default (regardless of the platform) provide their resources in a folder called resources inside each module.
Problem is that the default folder for Android needs to be called res
So you can apply a fix either way:
Change resources folders to res and modify gradle accordingly or indicate in the Android project that the resource folder is not res but resources.
We ended up doing the latter in our project
// build.gradle.kts
android {
...
sourceSets["main"].res.srcDirs(
"src/commonMain/resources",
"src/androidMain/resources"
)
...
}

Related

How to import KotlinMultiplatformExtension inside buildSrc module?

I am developing a kotlin multiplatform project, which has a bunch of modules.
I have written an extension function which is meant to be used inside each module. The extension function extends functionality of KotlinMultiplatformExtension class. Now that code is repeated inside each module's build.gradle.kts file. So i thought it would be great to move that code to buildSrc moudle and reuse everywhere.
The problem is that inside buildSrc module KotlinMultiplatformExtension is not resolved.
My buildSrc/build.gradle.kts:
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
If i right click KotlinMultiplatformExtension inside someModule/build.gradle.kts
it takes me to:
So I guessed that adding a dependency inside buildSrc/build.gradle.kts should help:
dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
}
But adding that results with an error:
* Exception is:
java.lang.NoClassDefFoundError: com/android/build/gradle/BaseExtension
at org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.configureTarget(KotlinPlugin.kt:765)
at org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin$Companion.applyToTarget(KotlinPlugin.kt:727)
at org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin.apply(KotlinPlugin.kt:689)
at org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin.apply(KotlinPlugin.kt:678)
at org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper.apply(KotlinPluginWrapper.kt:102)
Any ideas how to make KotlinMultiplatformExtension available inside buildSrc?
Turns out that changing
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
into
compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
resolves problem with the exception (java.lang.NoClassDefFoundError: com/android/build/gradle/BaseExtension)
and makes KotlinMultiplatformExtension available inside the buildSrc's source files.
solution found here:
https://github.com/gradle/gradle/issues/9209

How to create a Kotlin console application with Gradle in Intellij IDEA

I found this tutorial from JetBrains: https://www.jetbrains.com/help/idea/create-your-first-kotlin-app.html?section=Gradle%20Kotlin
It is dated August 19th, 2020.
I am using the same IntelliJ IDEA version as in their documentation: 2020.2.
However, my project creation wizard looks quite different from theirs.
They provide this screenshot:
But for me, it looks like this:
and when I click on Next:
I don't see where I can choose the Console Application template, or Gradle.
I found a second tutorial - https://kotlinlang.org/docs/tutorials/jvm-get-started.html , which shows yet a third variation of the New Project wizard:
Are the tutorials out of date? Am I doing anything wrong? How do I create a Kotlin project, based on a console application template, with Gradle?
The wizard you have seems to be obsolete now. There was a brand-new one, released as a part of Kotlin 1.4 recently(see here). Most probably, the problem is caused by the Kotlin IDE plugin being outdated or something. Please try to delete in and re-install using the Preferences -> Plugins menu. Comment here with the results, please. I'd like to know if this would help.
Indeed it's quite weird, I've never seen the dialog to look like yours (mine looks like the one in the tutorials). However, choosing the template doesn't do anything special - it simply creates the main file, which you can do so yourself.
So create a new project with the "JVM/IDEA" option. If it already opens up a main.kt file, you don't need to do anything else. If it didn't, look in the src folder - you should see a folder named main with a folder named kotlin (with a blue icon instead of grey) inside - here's where you wanna create your main file (right click -> new kotlin file/class -> main.kt and make it a file, not a class). Finally, put this in the file:
fun main(args: Array<String>) {
println("Hello world!")
}
Note: if you don't have a kotlin folder, create the file in the folder with the blue icon (might even be src). Also, if this doesn't use Gradle (for some reason), create a Gradle project instead, and at the "Additional libraries and frameworks" option, uncheck Java and check Kotlin, then continue with creating main.kt if it isn't created.
You may create a Kotlin + gradle project from the terminal:
$mkdir myProject; cd myProject; gradle init
follow the tutorial.
And then start the Intellij & open the dir
You're good to go
Same process like this
The same happened to me but I figured out how to fix it:
Just disable Material Theme UI.

Intellij IDEA plugin development. Action "create kotlin class"

I want to create a plugin for Intellij IDEA. I need to add an action (AnAction) that will create a class in Kotlin (not Java) in a custom package. I have two questions:
How to create files with the desired extension?
Or how to create a file with Kotlin class(from some base class) in a custom package?
One possible way to accomplish this is to use PsiFileFactory.createFileFromText() to create an in-memory Kotlin file and then to pass that file as a parameter to PsiDirectory.add() to save it to the filesystem.
Although yole's answer is correct, I would like to see more details about mistery PsiDirectory class.
//get directory by VirtualFile
PsiDirectory directory = PsiManager.getInstance(project).findDirectory((getKotlinSourceDir(project))
Get kotlin source dir:
private VirtualFile getKotlinSourceDir(Project project) {
return project.getBaseDir().findChild("src").findChild("main").findChild("kotlin");
}
And than you can create subdirectories:
//someDirectoryName it is simple name
//(i.e if you post "com.some.package" - it does not create com/some/package folder)
PsiDirectory newDirectory = psiDirectory.createSubdirectory(someDirectoryName);

Xtend in IntelliJ IDEA not generate file in src-gen

I combine Xtext and Xtend. In project, where I write code for my DSL, Xtext work but XTend not generate file in src-gen (this is sources root on: <project-root>/src-gen/).
I have this code in function doGenerate
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
fsa.generateFile("a.txt",'a')
}
Src-gen is always empty. In eclipse this work. How can I generate file in IntelliJ IDEA or how can I fix this problem. I run in gradle.
I run gradle task runIdea. I create Java project without any SDK.
When project is created, I add "file.mydsl" in src folder. Then I need change facet settings. I open project structure dialog (Ctrl+Shift+Alt+S), in the left-hand panel, click Facets, choose + icon and add DSL facet. Then apply and code is work. In src-gen create a file "a.txt".

How to create subprojects inside Play with Intellij?

Currently I have the following Play project structure:
PlayApp
modules
common
sub_project_two
PlayApp is marked as a module, dependent on common.
modules is just a directory.
common is a sub project(also a play app).
sub_project_two is a sub project(also a play app), which is dependent on common.
Unfortunately I cannot just right click on "modules" and create new module(play app) and move on. Currently, I literally have to right click PlayApp and create the new module then move it to "modules", and it is running into dependency issues in Intellij and failing to import the classes inside "common".
What is the correct way of creating subprojects inside Intellij?
There is no any special way to create subprojects in Intellij. Subprojects are defined in sbt build file. Intellij will discover these projects and configure them as long as you have Scala plugin. I would imagine a following project structure in your build file:
lazy val PlayApp = Project("playApp", file(".")).aggregate(common, subProjectTwo)
lazy val common = Project("common", file("modules/common"))
lazy val subProjectTwo = Project("subProjectTwo", file("modules/sub_project_two"))
For more details visit: http://www.scala-sbt.org/0.13.5/docs/Getting-Started/Multi-Project.html