分享

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

 ShangShujie 2008-03-28

我们有些程序会想要托盘处显示图标,最小化到系统栏;关闭按钮不关闭程序,也是最小化到系统栏;点击托盘图标激活窗口,通过托盘图标的弹出菜单来退出程序。

本段代码就是要完成这样的功能,是 SWT  来实现的。

直接代码给出,代码中有较详细的注释,说明了本程序的功能及实现。文中的任务栏和系统栏应该知道是指哪一段吧,微软就是这么定义的,用 spyxx 的 findwindow 窥探一下就知道了。

  1. package com.unmi;  
  2.   
  3. import org.eclipse.swt.*;  
  4. import org.eclipse.swt.events.*;  
  5. import org.eclipse.swt.graphics.*;  
  6. import org.eclipse.swt.widgets.*;  
  7.   
  8. /** 
  9.  * SWT 3.0 开始引入了 Tray,可以在系统栏放置你的程序图标了 
  10.  * 本程序实现的功能有四: 
  11.  * 1. 点击窗口的最小化或关闭按钮都是隐藏窗口--任务栏里不显示,不退出程序 
  12.  * 2. 窗口隐藏时,任务栏无图标,系统栏有图标;窗口处于显示状态时则恰好相反 
  13.  * 3. 窗口隐藏时可通过单击系统栏图标或点击系统栏的 "显示窗口" 菜单显示窗口 
  14.  * 4. 程序只能通过点击系统栏的 "退出程序" 菜单项退出,窗口的 X 按钮无效 
  15.  * @author Unmi 
  16.  * 
  17.  */  
  18. public class TrayExample {  
  19.   
  20.     public static void main(String[] args) {  
  21.         Display display = new Display();  
  22.           
  23.         //禁用掉了最大化按钮  
  24.         final Shell shell = new Shell(display,SWT.SHELL_TRIM ^ SWT.MAX);  
  25.         shell.setText("TrayExample");  
  26.   
  27.         //取系统中预置的图标,省得测试运行时还得加个图标文件  
  28.         shell.setImage(display.getSystemImage(SWT.ICON_WORKING));  
  29.   
  30.         //构造系统栏控件  
  31.         final Tray tray = display.getSystemTray();  
  32.         final TrayItem trayItem = new TrayItem(tray, SWT.NONE);  
  33.           
  34.         //程序启动时,窗口是显示的,所以系统栏图标隐藏  
  35.         trayItem.setVisible(false);  
  36.         trayItem.setToolTipText(shell.getText());  
  37.                       
  38.         trayItem.addSelectionListener(new SelectionAdapter() {  
  39.             public void widgetSelected(SelectionEvent e) {  
  40.                 toggleDisplay(shell, tray);  
  41.             }  
  42.         });  
  43.   
  44.         final Menu trayMenu = new Menu(shell, SWT.POP_UP);  
  45.         MenuItem showMenuItem = new MenuItem(trayMenu, SWT.PUSH);  
  46.         showMenuItem.setText("显示窗口(&s)");  
  47.           
  48.         //显示窗口,并隐藏系统栏中的图标  
  49.         showMenuItem.addSelectionListener(new SelectionAdapter() {  
  50.             public void widgetSelected(SelectionEvent event) {  
  51.                 toggleDisplay(shell, tray);  
  52.             }  
  53.         });  
  54.           
  55.         trayMenu.setDefaultItem(showMenuItem);  
  56.   
  57.         new MenuItem(trayMenu, SWT.SEPARATOR);  
  58.   
  59.         //系统栏中的退出菜单,程序只能通过这个菜单退出  
  60.         MenuItem exitMenuItem = new MenuItem(trayMenu, SWT.PUSH);  
  61.         exitMenuItem.setText("退出程序(&x)");  
  62.   
  63.         exitMenuItem.addSelectionListener(new SelectionAdapter() {  
  64.             public void widgetSelected(SelectionEvent event) {  
  65.                 shell.dispose();  
  66.             }  
  67.         });  
  68.   
  69.         //在系统栏图标点击鼠标右键时的事件,弹出系统栏菜单  
  70.         trayItem.addMenuDetectListener(new MenuDetectListener(){  
  71.             public void menuDetected(MenuDetectEvent e) {  
  72.                 trayMenu.setVisible(true);  
  73.             }  
  74.         });  
  75.   
  76.         trayItem.setImage(shell.getImage());  
  77.   
  78.         //注册窗口事件监听器  
  79.         shell.addShellListener(new ShellAdapter() {  
  80.               
  81.             //点击窗口最小化按钮时,窗口隐藏,系统栏显示图标  
  82.             public void shellIconified(ShellEvent e) {  
  83.                 toggleDisplay(shell, tray);  
  84.             }  
  85.               
  86.             //点击窗口关闭按钮时,并不终止程序,而时隐藏窗口,同时系统栏显示图标  
  87.             public void shellClosed(ShellEvent e) {  
  88.                 e.doit = false//消耗掉原本系统来处理的事件  
  89.                 toggleDisplay(shell, tray);  
  90.             }  
  91.         });  
  92.   
  93.         shell.setSize(320240);  
  94.         center(shell);  
  95.         shell.open();  
  96.         while (!shell.isDisposed()) {  
  97.             if (!display.readAndDispatch())  
  98.                 display.sleep();  
  99.         }  
  100.         display.dispose();  
  101.     }  
  102.   
  103.     /** 
  104.      * 窗口是可见状态时,则隐藏窗口,同时把系统栏中图标删除 
  105.      * 窗口是隐藏状态时,则显示窗口,并且在系统栏中显示图标 
  106.      * @param shell 窗口 
  107.      * @param tray 系统栏图标控件 
  108.      */  
  109.     private static void toggleDisplay(Shell shell, Tray tray) {  
  110.         try {  
  111.             shell.setVisible(!shell.isVisible());  
  112.             tray.getItem(0).setVisible(!shell.isVisible());  
  113.             if (shell.getVisible()) {  
  114.                 shell.setMinimized(false);  
  115.                 shell.setActive();  
  116.             }  
  117.         } catch (Exception e) {  
  118.             e.printStackTrace();  
  119.         }  
  120.     }  
  121.       
  122.     /** 
  123.      * 窗口居中显示 
  124.      * @param shell 要显示的窗口 
  125.      */  
  126.     private static void center(Shell shell){  
  127.         Monitor monitor = shell.getMonitor();  
  128.         Rectangle bounds = monitor.getBounds ();  
  129.         Rectangle rect = shell.getBounds ();  
  130.         int x = bounds.x + (bounds.width - rect.width) / 2;  
  131.         int y = bounds.y + (bounds.height - rect.height) / 2;  
  132.         shell.setLocation (x, y);  
  133.     }  
  134. }  


实现效果如下:

SwtNoTray.jpg                    SwtHasTray.jpg

左图是窗口显示时,系统栏中无图标,而任务栏中有图标。右图是窗口隐藏时,只有系统栏有图标。

过后,看了翻译软件 LINGOES 灵格斯的表现形式是:

1. 任何时候系统栏都有图标
2. 最小化按钮不会隐藏窗口,只是最小化到任务栏
3. 关闭按钮也是不会关闭程序,而是最小化到系统栏
4. 也是只能通过托盘图标的弹出菜单项“退出” 来关闭程序

参考:http://www./bbs/read-cec-tid-15458-fpage-9.html

但最后还留有一个问题:如何实现窗口可见状态时,任务栏里什么都不显示呢?

 




[版权声明]
本 站内文章,如未标注 [转载],均系原创或翻译之作,本人 Unmi 保留一切权利。本站原创及译作未经本人许可,不得用于商业用途及传统媒体。网络媒体可随意转载,或以此为基础进行演译,但务必以链接形式注明原始出处和作 者信息,否则属于侵权行为。另对本站转载他处文章,俱有说明,如有侵权请联系本人,本人将会在第一时间删除侵权文章。及此说明,重之之重。
posted on 2008-03-23 16:05 隔叶黄莺 阅读(796) 评论(3)  编辑  收藏
# 

Feedback

# re: SWT 中实现最小化到托盘图标,并只能通过托盘的弹出菜单关闭程序 2008-03-24 23:45 千里冰封
你写的窗口如果是继承自JDialog的话,则任务栏什么也不会显示  回复  更多评论
  

# re: SWT 中实现最小化到托盘图标,并只能通过托盘的弹出菜单关闭程序 2008-03-24 23:46 千里冰封
# while (!shell.isDisposed()) {
# if (!display.readAndDispatch())
# display.sleep();
# }
怎么像MFC的事件循环哦,
唉,SWT就是和SWING没法比了  回复  更多评论
  

# re: SWT 中实现最小化到托盘图标,并只能通过托盘的弹出菜单关闭程序 2008-03-25 10:38 隔叶黄莺
SWT的程序如果继承自 JDialog 就不伦不类了,也没这么试过,用SWT一般也不建议这么做,虽然SWT也提供了 SWT-AWT 相应类

SWT 确实很多东西太像 MFC 的,比如
窗口构造方式:
final Shell shell = new Shell(display,SWT.SHELL_TRIM ^ SWT.MAX);

SWT中很多变量在MFC都有相应的全局常量对应

资源的获取方式:
display.getSystemImage(SWT.ICON_WORKING

不过SWT可还是比MFC简单多了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多