You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中实现类似Swing pack()的窗口适配内容功能

实现Compose Desktop窗口适配内容(类似Swing pack())

核心问题原因

你设置的WindowState(width = 500.dp, height = 500.dp)是窗口的整体外部尺寸,但系统窗口的标题栏、边框等装饰会占用一部分空间,导致实际可展示内容的区域被压缩,因此出现内容截断的情况。

解决方案一:使用官方sizeToContent参数(推荐)

Compose Desktop 1.2及以上版本提供了sizeToContent参数,可让窗口自动适配内容大小,完全对应Swing的pack()功能。

修改后的代码如下:

fun main() = application {
    Window(
        onCloseRequest = ::exitApplication,
        sizeToContent = SizeToContent.WidthAndHeight,
        resizable = false
    ) {
        // 给内容设置固定的500×500像素尺寸
        Surface(color = Color.Black, modifier = Modifier.size(500.dp)) {
            Canvas(modifier = Modifier.fillMaxSize()) {
                withTransform(transformBlock = {
                    scale(500.0f, 500.0f, pivot = Offset.Zero)
                }) {
                    drawLine(color = Color.Blue, start = Offset(0.0f, 0.0f), end = Offset(1.0f, 1.0f))
                    drawLine(color = Color.Blue, start = Offset(1.0f, 0.0f), end = Offset(0.0f, 1.0f))
                }
            }
        }
    }
}
  • 移除手动设置的WindowState,改用sizeToContent = SizeToContent.WidthAndHeight,窗口会自动包裹内容。
  • 给Surface设置Modifier.size(500.dp),确保内容区域固定为500×500像素,窗口会自动加上系统装饰所需的空间,最终内容不会被截断。

解决方案二:手动计算窗口尺寸(兼容旧版本)

如果使用的是低于1.2的Compose Desktop版本,可以手动读取系统窗口装饰的Insets,计算出窗口需要的整体大小:

fun main() = application {
    val contentSize = 500.dp
    Window(
        onCloseRequest = ::exitApplication,
        resizable = false
    ) {
        // 获取窗口装饰的边距(标题栏、边框等占用的空间)
        val insets = window.insets
        // 计算窗口整体尺寸:内容尺寸 + 装饰边距
        val windowWidth = contentSize + insets.left.dp + insets.right.dp
        val windowHeight = contentSize + insets.top.dp + insets.bottom.dp

        // 窗口初始化后设置尺寸
        LaunchedEffect(Unit) {
            window.size = DpSize(windowWidth, windowHeight)
        }

        Surface(color = Color.Black, modifier = Modifier.size(contentSize)) {
            Canvas(modifier = Modifier.fillMaxSize()) {
                withTransform(transformBlock = {
                    scale(500.0f, 500.0f, pivot = Offset.Zero)
                }) {
                    drawLine(color = Color.Blue, start = Offset(0.0f, 0.0f), end = Offset(1.0f, 1.0f))
                    drawLine(color = Color.Blue, start = Offset(1.0f, 0.0f), end = Offset(0.0f, 1.0f))
                }
            }
        }
    }
}
  • 通过window.insets获取系统装饰占用的上下左右边距,将其加到内容尺寸上,得到窗口需要的整体大小。
  • 使用LaunchedEffect在窗口初始化完成后设置尺寸,确保计算准确。

内容的提问来源于stack exchange,提问作者Hakanai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:48:22