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

JetBrains Compose/Swing:如何获取系统托盘图标坐标并定位窗口?

实现JetBrains Compose桌面应用窗口初始定位在系统托盘附近

我正在使用JetBrains Compose开发桌面应用,也接受基于底层Swing的解决方案。希望实现一个功能:让应用窗口初始时位于系统托盘图标附近,类似JetBrains Toolbox的效果(将无装饰窗口放置在托盘图标旁)。

示例

截图示例效果展示
截图示例效果展示

我曾尝试通过鼠标事件检测托盘图标点击来定位窗口,但该方案无法达到预期效果:虽然能运行,但窗口有时会跳动(取决于点击位置),整体表现不佳。

窗口跳动效果

我之前的解决方案

我将自己的方案分享出来,供有需要的人参考:

internal object XTray {

    fun initialize(image: Image, onClick: (x: Int, y: Int) -> Unit) {
        createTrayIcon(image, onClick)
    }

    private fun createTrayIcon(
        image: Image,
        onClick: (x: Int, y: Int) -> Unit,
    ): TrayIcon {
        val systemTray = SystemTray.getSystemTray()

        val trayIcon = TrayIcon(image, "Open X")

        trayIcon.popupMenu = PopupMenu("X")

        trayIcon.addMouseListener(createTrayMouseListener { x, y ->
            onClick(x, y)
        })

        systemTray.add(trayIcon)

        return trayIcon
    }

    private fun createTrayMouseListener(
        onClick: (x: Int, y: Int) -> Unit,
    ): MouseAdapter {
        return object : MouseAdapter() {
            override fun mouseClicked(e: MouseEvent?) {
                e ?: return

                if (SwingUtilities.isLeftMouseButton(e)) {
                    println("${e.x} & ${e.y}")
                    onClick(calculateWindowX(e.x), calculateWindowY(e.y))
                }
            }
        }
    }

    private fun calculateWindowX(
        trayCenterX: Int,
        windowWidth: Int = 350,
        screenWidth: Int = Toolkit.getDefaultToolkit().screenSize.width,
    ): Int {
        val halfWindowWidth = windowWidth / 2

        return when {
            trayCenterX - halfWindowWidth < 0 -> 0 // 托盘图标靠近左边缘
            trayCenterX + halfWindowWidth > screenWidth -> screenWidth - windowWidth // 托盘图标靠近右边缘
            else -> trayCenterX - halfWindowWidth // 托盘图标位于屏幕中间
        }
    }

    private fun calculateWindowY(
        trayCenterY: Int,
        windowHeight: Int = 650,
        screenHeight: Int = Toolkit.getDefaultToolkit().screenSize.height,
    ): Int {
        val halfWindowHeight = windowHeight / 2

        return when {
            trayCenterY - halfWindowHeight < 0 -> 0 // 托盘图标靠近上边缘
            trayCenterY + halfWindowHeight > screenHeight -> screenHeight - windowHeight // 托盘图标靠近下边缘
            else -> trayCenterY - halfWindowHeight // 托盘图标位于屏幕中间
        }
    }
}

像JetBrains Toolbox这类应用,启动时无需点击图标就能直接在托盘附近显示窗口,说明存在更优方案。我猜测需要调用系统API,但希望找到现成的解决方案或库来实现该功能(这是一个常见功能,不想重复造轮子),目前未找到相关示例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:03:14