SWT 中实现最小化到托盘图标,并只能通过托盘的弹出菜单关闭程序

SWT 3.0 开始引入了 Tray,可以在系统栏放置你的程序图标了
本程序实现的功能有:

  1. 点击窗口的最小化或关闭按钮都是隐藏窗口–任务栏里不显示,不退出程序
  2. 窗口隐藏时,任务栏无图标,系统栏有图标;窗口处于显示状态时则恰好相反
  3. 窗口隐藏时可通过单击系统栏图标或点击系统栏的 “显示窗口” 菜单显示窗口
  4. 程序只能通过点击系统栏的 “退出程序” 菜单项退出,窗口的 X 按钮无效
import org.eclipse.swt.SWT
import org.eclipse.swt.events.*
import org.eclipse.swt.widgets.*


fun main() {
    TrayExample.show()
}

/**
 * SWT 3.0 开始引入了 Tray,可以在系统栏放置你的程序图标了
 * 本程序实现的功能有四:
 * 1. 点击窗口的最小化或关闭按钮都是隐藏窗口--任务栏里不显示,不退出程序
 * 2. 窗口隐藏时,任务栏无图标,系统栏有图标;窗口处于显示状态时则恰好相反
 * 3. 窗口隐藏时可通过单击系统栏图标或点击系统栏的 "显示窗口" 菜单显示窗口
 * 4. 程序只能通过点击系统栏的 "退出程序" 菜单项退出,窗口的 X 按钮无效
 */
object TrayExample {
    fun show() {
        val display = Display()

        //禁用掉了最大化按钮
        val shell = Shell(display, SWT.SHELL_TRIM xor SWT.MAX)
        shell.text = "TrayExample"

        //取系统中预置的图标,省得测试运行时还得加个图标文件
        shell.image = display.getSystemImage(SWT.ICON_WORKING)

        //构造系统栏控件
        val tray = display.systemTray
        val trayItem = TrayItem(tray, SWT.NONE)

        //程序启动时,窗口是显示的,所以系统栏图标隐藏
        trayItem.visible = false
        trayItem.toolTipText = shell.text

        trayItem.addSelectionListener(SelectionListener.widgetSelectedAdapter {
            toggleDisplay(
                shell, tray
            )
        })

        val trayMenu: Menu = getTrayMenu(shell, tray)

        //在系统栏图标点击鼠标右键时的事件,弹出系统栏菜单
        trayItem.addMenuDetectListener { trayMenu.isVisible = true }

        trayItem.image = shell.image

        //注册窗口事件监听器
        shell.addShellListener(object : ShellAdapter() {
            //点击窗口最小化按钮时,窗口隐藏,系统栏显示图标
            override fun shellIconified(e: ShellEvent) {
                toggleDisplay(shell, tray)
            }

            //点击窗口关闭按钮时,并不终止程序,而时隐藏窗口,同时系统栏显示图标
            override fun shellClosed(e: ShellEvent) {
                e.doit = false //消耗掉原本系统来处理的事件
                toggleDisplay(shell, tray)
            }
        })

        shell.setSize(320, 240)
        center(shell)
        shell.open()
        while (!shell.isDisposed) {
            if (!display.readAndDispatch()) {
                display.sleep()
            }
        }
        display.dispose()
    }
}

private fun getTrayMenu(shell: Shell, tray: Tray): Menu {
    val trayMenu = Menu(shell, SWT.POP_UP)
    val showMenuItem = MenuItem(trayMenu, SWT.PUSH)
    showMenuItem.text = "显示窗口(&s)"

    //显示窗口,并隐藏系统栏中的图标
    showMenuItem.addSelectionListener(SelectionListener.widgetSelectedAdapter {
        toggleDisplay(
            shell, tray
        )
    })
    trayMenu.defaultItem = showMenuItem
    MenuItem(trayMenu, SWT.SEPARATOR)

    //系统栏中的退出菜单,程序只能通过这个菜单退出
    val exitMenuItem = MenuItem(trayMenu, SWT.PUSH)
    exitMenuItem.text = "退出程序(&x)"
    exitMenuItem.addSelectionListener(object : SelectionAdapter() {
        override fun widgetSelected(event: SelectionEvent) {
            shell.dispose()
        }
    })
    return trayMenu
}

/**
 * 窗口是可见状态时,则隐藏窗口,同时把系统栏中图标删除
 * 窗口是隐藏状态时,则显示窗口,并且在系统栏中显示图标
 *
 * @param shell 窗口
 * @param tray 系统栏图标控件
 */
private fun toggleDisplay(shell: Shell, tray: Tray) {
    shell.isVisible = !shell.isVisible
    tray.getItem(0).visible = !shell.isVisible
    if (shell.visible) {
        shell.minimized = false
        shell.setActive()
    }
}

/**
 * 窗口居中显示
 *
 * @param shell 要显示的窗口
 */
private fun center(shell: Shell) {
    val monitor = shell.monitor
    val bounds = monitor.bounds
    val rect = shell.bounds
    val x = bounds.x + (bounds.width - rect.width) / 2
    val y = bounds.y + (bounds.height - rect.height) / 2
    shell.setLocation(x, y)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值