Kotlin equivalent of jcefmaven with a more modern setup and depending on JetBrains/jcef
Visit the JCEF repo at JetBrains/jcef and the jcefmaven repo at jcefmaven/jcefmaven
Please take a look at JetBrains/JetBrainsRuntime for a full list of supported targets.
OS | Arch |
---|---|
amd64, aarch64 | |
amd64, aarch64 | |
amd64, aarch64 |
This library is published to Maven Central.
repositories {
mavenCentral()
maven("https://jogamp.org/deployment/maven")
}
The version depends on JetBrains/JetBrainsRuntime and JetBrains/jcef.
Take a look at the releases for more details.
dependencies {
implementation("dev.datlag:kcef:$version")
// or with version catalog
implementation(libs.kcef)
}
[versions]
kcef = "2023.10.11.1" # put your wanted version here
[libraries]
kcef = { group = "dev.datlag", name = "kcef", version.ref = "kcef" }
View Compose specific usage here COMPOSE
It's recommended to initialize KCEF
directly after starting the application.
This way users don't have to wait when the CefBrowser
is used in another UI page.
Kotlin
This is recommended to be called in a Coroutine with IO scope.
KCEF.init(
builder = {
progress {
onDownloading {
println("Download progress: $it%")
}
}
release(true)
}
)
Java
This is recommended to be called in a IO Thread.
KCEF.initBlocking(
new KCEFBuilder().progress(
new KCEFBuilder.InitProgress.Builder().onDownloading(progress -> {
System.out.println("Download progress: " + progress + "%");
}).build()
).release(true),
throwable -> {
if (throwable != null) {
throwable.printStackTrace();
}
},
() -> {
System.out.println("Restart required");
}
);
Kotlin
If you listen to the onInitialized
progress in the KCEF.init
method, you can get the client blocking on the Main Thread.
if (initialized) {
val client = KCEF.newClientBlocking()
}
Otherwise, you should run this in a Coroutine which is not using the Main scope.
KCEF.newClient()
The above methods may throw a CefException
, you can use the nullable equivalent instead.
if (initialized) {
val client: KCEFClient? = KCEF.newClientOrNullBlocking { throwable ->
throwable?.printStackTrace()
}
}
/** Needs to be called in a coroutine */
val client: KCEFClient? = KCEF.newClientOrNull { throwable ->
throwable?.printStackTrace()
}
Java
If you listen to the onInitialized
progress in the KCEF.init
method, you can get the client blocking on the Main Thread.
if (initialized) {
KCEFClient client = KCEF.newClientBlocking();
}
Otherwise, you should run this in a new Thread.
/** Run in a new Thread */
KCEFClient client = KCEF.newClientBlocking();
The above methods may throw a CefException
, you can use the nullable equivalent instead.
if (initialized) {
KCEFClient client = KCEF.newClientOrNullBlocking(throwable -> {
if (throwable != null) {
throwable.printStackTrace();
}
});
}
/** Should be called in a new Thread */
KCEFClient client = KCEF.newClientOrNullBlocking(throwable -> {
if (throwable != null) {
throwable.printStackTrace();
}
});
If the CefClient
is no longer used, make sure to dispose it.
client.dispose()
If you no longer need any CEF instance, cleanup up using the KCEF
class.
KCEF.disposeBlocking()
or, if you're not sure if the KCEF.init
process is finished
KCEF.dispose()
Some platforms require the addition of specific flags. To use on MacOSX, add the following JVM flags:
--add-opens java.desktop/sun.awt=ALL-UNNAMED
--add-opens java.desktop/sun.lwawt=ALL-UNNAMED
--add-opens java.desktop/sun.lwawt.macosx=ALL-UNNAMED
For gradle project, you can configure it in the build.gradle.kts like that:
afterEvaluate {
tasks.withType<JavaExec> {
if (System.getProperty("os.name").contains("Mac")) {
jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
jvmArgs("--add-opens", "java.desktop/sun.lwawt=ALL-UNNAMED")
jvmArgs("--add-opens", "java.desktop/sun.lwawt.macosx=ALL-UNNAMED")
}
}
}
If your application build type uses ProGuard, commonly used for release builds in Java and Kotlin applications, you have to add ProGuard rules for KCEF to work.
-keep class org.cef.** { *; }
-keep class kotlinx.coroutines.swing.SwingDispatcherFactory
Sponsoring to this project means sponsoring to all my projects! So the further text is not to be attributed to this project, but to all my apps and libraries.
Supporting this project helps to keep it up-to-date. You can donate if you want or contribute to the project as well. This shows that the library is used by people, and it's worth to maintain.