Vad*_*huk 5 java desktop swing kotlin 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 // Tray icon is closer to the left edge
trayCenterX + halfWindowWidth > screenWidth -> screenWidth - windowWidth // Tray icon is closer to the right edge
else -> trayCenterX - halfWindowWidth // Tray icon is in the middle of the screen
}
}
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 // Tray icon is closer to the top edge
trayCenterY + halfWindowHeight > screenHeight -> screenHeight - windowHeight // Tray icon is closer to the bottom edge
else -> trayCenterY - halfWindowHeight // Tray icon is in the middle of the screen
}
}
}
Run Code Online (Sandbox Code Playgroud)
其他应用程序(例如 JetBrains Toolbox)在启动时显示其窗口,无需通过单击图标来找到该图标。所以,应该有另一个解决方案。
我怀疑我需要使用系统 API 来完成此任务,但我想知道是否有现成的解决方案或库可以提供此功能。这似乎是一个常见的功能,我不想重新发明轮子。
我想看看例子,但我找不到它们。
小智 0
Java 中的系统托盘 API 允许您与托盘图标进行交互(添加、删除、更新其图像或工具提示等),但它不提供查询其在屏幕上的位置的方法。与托盘图标关联的鼠标事件提供相对于图标本身的坐标,而不是相对于屏幕的坐标。
在 Windows 上,您需要与管理系统托盘区域及其图标的 Shell_TrayWnd 和 TrayNotifyWnd Windows 控件进行交互。这需要调用 Windows API 函数并处理 Windows 消息,这不能直接在 Java 中完成,但需要使用 JNI 或第三方库,如 JNA (Java Native Access) 或 JNR (Java Native Runtime)。
| 归档时间: |
|
| 查看次数: |
228 次 |
| 最近记录: |