Created
July 7, 2022 11:11
-
-
Save AlexGladkov/bb935e43406ee4c6b40036cca01b1c0b to your computer and use it in GitHub Desktop.
Desktop Web View
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
plugins { | |
kotlin("multiplatform") | |
id("org.openjfx.javafxplugin") version "0.0.10" | |
} | |
kotlin { | |
jvm("desktop") { | |
compilations.all { | |
kotlinOptions { | |
jvmTarget = "11" | |
} | |
withJava() | |
} | |
} | |
sourceSets { | |
val desktopMain by getting { | |
dependencies { | |
implementation(compose.desktop.currentOs) | |
//Optional other deps | |
implementation(compose.uiTooling) | |
implementation(compose.runtime) | |
implementation(compose.foundation) | |
implementation(compose.material) | |
implementation(compose.animation) | |
implementation(compose.animationGraphics) | |
} | |
} | |
} | |
} | |
javafx { | |
version = "17" | |
modules = listOf("javafx.controls", "javafx.swing", "javafx.web", "javafx.graphics") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun DesktopWebView() { | |
val finishListener = object : PlatformImpl.FinishListener { | |
override fun idle(implicitExit: Boolean) {} | |
override fun exitCalled() {} | |
} | |
PlatformImpl.addListener(finishListener) | |
println("Desktop Web View start") | |
Window( | |
title = "Web View Test", | |
resizable = false, | |
state = WindowState( | |
placement = WindowPlacement.Floating, | |
size = DpSize(400.dp, 400.dp) | |
), | |
onCloseRequest = { | |
PlatformImpl.removeListener(finishListener) | |
}, | |
content = { | |
val jfxPanel = remember { JFXPanel() } | |
Box(modifier = Modifier.fillMaxSize()) { | |
ComposeJFXPanel( | |
composeWindow = window, | |
jfxPanel = jfxPanel, | |
onCreate = { | |
Platform.runLater { | |
val root = WebView() | |
val engine = root.engine | |
val scene = Scene(root) | |
engine.loadWorker.stateProperty().addListener { _, _, newState -> | |
if (newState === Worker.State.SUCCEEDED) { | |
println("State ${newState.name}") | |
} | |
} | |
engine.loadWorker.exceptionProperty().addListener { _, _, newError -> | |
println("page load error : $newError") | |
} | |
jfxPanel.scene = scene | |
engine.load("http://google.com") // can be a html document from resources .. | |
engine.setOnError { error -> println("onError : $error") } | |
} | |
}, onDestroy = { | |
Platform.runLater { | |
} | |
} | |
) | |
} | |
} | |
) | |
} | |
@Composable | |
fun ComposeJFXPanel( | |
composeWindow: ComposeWindow, | |
jfxPanel: JFXPanel, | |
onCreate: () -> Unit, | |
onDestroy: () -> Unit = {} | |
) { | |
val jPanel = remember { JPanel() } | |
val density = LocalDensity.current.density | |
Layout( | |
content = {}, | |
modifier = Modifier.onGloballyPositioned { childCoordinates -> | |
childCoordinates.parentCoordinates?.let { layoutCoordinates -> | |
val location = layoutCoordinates.localToWindow(Offset.Zero).round() | |
val size = layoutCoordinates.size | |
jPanel.setBounds( | |
(location.x / density).toInt(), | |
(location.y / density).toInt(), | |
(size.width / density).toInt(), | |
(size.height / density).toInt() | |
) | |
jPanel.validate() | |
jPanel.repaint() | |
} | |
}, | |
measurePolicy = { _, _ -> layout(0,0) {} } | |
) | |
DisposableEffect(jPanel) { | |
composeWindow.add(jPanel) | |
jPanel.layout = BorderLayout(0, 0) | |
jPanel.add(jfxPanel) | |
onCreate() | |
onDispose { | |
onDestroy() | |
composeWindow.remove(jPanel) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment