Closed wangzhigang1112 closed 1 year ago
You can do something like this:
var isScrollbarShown by remember { mutableStateOf<Boolean>(false) }
if (isScrollbarShown) {
VerticalScrollbar(...)
}
and control its visibility by changing the value of the mutable state.
I use javafx lib for compose, I need the ability of webview。
When the height of the webpage content exceeds the height of the window, the vertical scroll bar of the window is displayed, and I don't need it to be displayed.
my build.gradle.kts: `import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins { kotlin("multiplatform") id("org.openjfx.javafxplugin") version "0.0.13" id("org.jetbrains.compose") }
group = "com.epoint.app" version = "1.0-SNAPSHOT"
repositories { maven("https://jitpack.io")
google()
mavenCentral()
}
kotlin { jvm { jvmToolchain(11) withJava() } sourceSets { val jvmMain by getting { dependencies { implementation(compose.desktop.currentOs) //本地sqlite据库 implementation("org.xerial:sqlite-jdbc:3.34.0") //kotlin 网络请求库 implementation("io.ktor:ktor-client-core:2.2.3") implementation("io.ktor:ktor-client-cio:2.2.3") // implementation("io.ktor:ktor-client-apache:2.2.3") implementation("io.ktor:ktor-client-content-negotiation:2.2.3") implementation("io.ktor:ktor-serialization-kotlinx-json:2.2.3") implementation("io.ktor:ktor-serialization-kotlinx-xml:2.2.3") implementation("io.ktor:ktor-serialization-kotlinx-cbor:2.2.3") implementation("io.ktor:ktor-serialization-kotlinx-protobuf:2.2.3") implementation("io.ktor:ktor-client-logging:2.2.3") //阿里json库 implementation("com.alibaba:fastjson:1.2.83") //日志库 implementation("ch.qos.logback:logback-classic:1.2.11")
implementation(files("src/libs/kmm.jar"))
}
}
val jvmTest by getting
}
}
compose.desktop { application { mainClass = "MainKt" nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "desktop" packageVersion = "1.0.0" } } }
//https://www.likecs.com/ask-7701835.html javafx { version = "20" modules = listOf("javafx.controls", "javafx.swing", "javafx.web", "javafx.graphics") }`
my compose code `@Composable fun EpointWebView(composeWindow: ComposeWindow, url: String) { val jfxPanel = remember { JFXPanel() } var jsObject = remember<JSObject?> { null }
Box(modifier = Modifier.fillMaxSize().background(Color.White)) {
lateinit var engine: WebEngine
Button(onClick = {
Platform.runLater {
engine.history.go(-1)
}
}) {
Text("上一页")
}
ComposeJFXPanel(
composeWindow = composeWindow,
jfxPanel = jfxPanel,
onCreate = {
Platform.runLater {
val root = WebView()
// 设置WebView自适应宽度和高度
println("w=" + composeWindow.size.width.toDouble())
println("h=" + composeWindow.size.height.toDouble())
root.setPrefWidth(composeWindow.size.width.toDouble());
root.setPrefHeight(composeWindow.size.height.toDouble());
val userAgent =
"Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_6 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0"
root.getEngine().setUserAgent(userAgent)
engine = root.engine
val scene = Scene(root)
engine.loadWorker.stateProperty().addListener { _, _, newState ->
println("newState=" + newState)
if (newState === Worker.State.SUCCEEDED) {
jsObject = root.engine.executeScript("window") as JSObject
// execute other javascript / setup js callbacks fields etc..
}
}
engine.loadWorker.exceptionProperty().addListener { _, _, newError ->
println("page load error : $newError")
}
jfxPanel.scene = scene
val file = File(url)
val loadFileStr = file.toURI().toURL().toString()
println("loadFileStr=" + loadFileStr)
engine.load(loadFileStr) // can be a html document from resources ..
engine.setOnError { error -> println("onError : $error") }
}
}, onDestroy = {
Platform.runLater {
jsObject?.let { jsObj ->
// clean up code for more complex implementations i.e. removing javascript callbacks etc..
}
}
})
}
}
@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 -> val coordinates = childCoordinates.parentCoordinates!! val location = coordinates.localToWindow(Offset.Zero).round() val size = coordinates.size jPanel.setBounds( (location.x / density).toInt(), (location.y / density).toInt() + 44, (size.width / density).toInt(), (size.height / density).toInt() - 44 ) 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)
}
}
}`
@wangzhigang1112 I looked into your issue. The scrollbar is coming from the JavaFX WebView
and is not related to Compose. Compose does not add any scroll behavior for boxes without a modifier by default.
However, to solve your issue, you have multiple options here:
overflow-y: hidden;
For option 1: Create a new resource file with the style override:
/* E.g. in src/jvmMain/resource/no-scrollbars.css */
body {
overflow-x: hidden; /* Hide horizontal bar */
overflow-y: hidden; /* Hide vertical bar */
overflow: hidden; /* or hide both */
}
And then load the CSS file when initializing the WebView
:
// In EpointWebView Composable
// ...
engine = root.engine
val scene = Scene(root)
root.engine.userStyleSheetLocation = this.javaClass.getResource("/no-scrollbars.css")?.toExternalForm()
// ...
For option 2:
// In EpointWebView Composable
// ...
engine.loadWorker.stateProperty().addListener { _, _, newState ->
println("newState=" + newState)
if (newState === Worker.State.SUCCEEDED) {
jsObject = root.engine.executeScript("window") as JSObject
engine.executeScript("document.body.style.overflow = 'hidden';") // <-- Override style here directly
// execute other javascript / setup js callbacks fields etc..
}
}
// ...
Solutions are inspired from https://stackoverflow.com/questions/11206942/how-to-hide-scrollbars-in-the-javafx-webview.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
how to hide scrollbar