RCP系统托盘实现方法
来源:互联网 发布:潮流计算软件 编辑:程序博客网 时间:2024/05/17 08:31
- RCP系统托盘气泡提示和右键菜单的实现
- 实现系统托盘将程序最小化到Windows托盘,是一项有趣而且实用的工作。程序启动后自动最小化到Windows托盘。即使关闭程序,用户也可以随时通过托盘打开,非常方便快捷。
- 托盘对象简介实现系统托盘首先需要获得Windows托盘对象,托盘对象可以通过Display对象的getSystemTray()方法取得,代码如下:
- Tray tray = window.getShell().getDisplay().getSystemTray();
- 托盘对象的创建应该是在能够获得Display对象之后而程序窗口又没有打开之前,即ApplicationWorkbenchWindowAdvisor的postWindowOpen()方法中。
- 然后,向托盘对象中添加托盘项目TrayItem,并设置托盘项目的文字、图标。托盘项目及其图标应该在程序退出时销毁以释放资源。托盘项目创建方法如下:
- TrayItem trayItem = new TrayItem(tray, SWT.NONE);
- trayItem.setImage(trayImage);
- trayItem.setToolTipText("文字说明");
- 最后,需要添加托盘项目的事件监听处理,主要有两种,一种是用户单击托盘图标时需要打开程序,其监听事件为:
- trayItem.addListener(SWT.Selection, new Listener() {
- public void handleEvent(Event event) {
-
- }
- });
- 另外一种是用户右键单击托盘图标时需要弹出菜单,其监听事件为:
- trayItem.addListener(SWT.MenuDetect, new Listener() {
- public void handleEvent(Event event) {
- });
- 最后还有一个问题,当用户关闭程序时不能关闭托盘图标。这需要复写Application- WorkbenchWindowAdvisor的preWindowShellClose()方法。
- 系统托盘的具体实现1.创建管理托盘的HookSysTray类,HookSysTray类实现托盘对象的创建和管理,其代码如下。
- cn.edu.jfcs.sys
- import …
- public class HookSysTray {
- private TrayItem trayItem;
- private Image trayImage;
- public HookSysTray() {}
- public void createSysTray(final IWorkbenchWindow window) {
- trayItem = initTrayItem(window);
- if (trayItem != null) {
- trayPopupMenu(window);
- trayMinimize(window);
- }
- }
-
- public void windowMinimized(final Shell shell) {
- shell.setMinimized(true);
- shell.setVisible(false);
- }
-
- private void trayMinimize(final IWorkbenchWindow window) {
- window.getShell().addShellListener(new ShellAdapter() {
- public void shellIconified(ShellEvent e) {
- window.getShell().setVisible(false);
- }
- });
-
-
- trayItem.addListener(SWT.Selection, new Listener() {
- public void handleEvent(Event event) {
- Shell shell = window.getShell();
- if (!shell.isVisible()) {
- shell.setVisible(true);
- window.getShell().setMinimized(false);
- }
- }
- });
- }
-
- private void trayPopupMenu(final IWorkbenchWindow window) {
- trayItem.addListener(SWT.MenuDetect, new Listener() {
- public void handleEvent(Event event) {
- MenuManager trayMenu = new MenuManager();
-
- Menu menu = trayMenu.createContextMenu(window.getShell());
- fillTrayItem(trayMenu, window);
- menu.setVisible(true);
- }
- });
- }
-
- private void fillTrayItem(IMenuManager trayItem,
- final IWorkbenchWindow window) {
-
- Action exitSystem = new Action("退出系统[&E]", AbstractUIPlugin
- .imageDescriptorFromPlugin(IAppConstants.APPLICATION_ID,
- IImageKey.EXIT_SYSTEM)) {
- public void run() {
- PlatformUI.getWorkbench().close();
- }
- };
- trayItem.add(new Logoff());
- trayItem.add(exitSystem);
- }
-
- private TrayItem initTrayItem(IWorkbenchWindow window) {
-
- final Tray tray = window.getShell().getDisplay().getSystemTray();
- if (tray == null)
- return null;
- trayItem = new TrayItem(tray, SWT.NONE);
- trayImage = AbstractUIPlugin.imageDescriptorFromPlugin(
- IAppConstants.APPLICATION_ID, IImageKey .WINDOW_IMAGE) .createImage();
- trayItem.setImage(trayImage);
- return trayItem;
- }
- public void Dispose() {
- if (trayItem != null) trayItem.dispose();
- if (trayImage != null) trayImage.dispose();
- }
- }
- 程序说明:
- 程序向Windows托盘增加一个托盘图标和提示文字,并添加“用户注销”和“退出系统”两个托盘项。
- MenuManager trayMenu = new MenuManager()是托盘的菜单管理器。
- ExitSystem作为“退出系统”托盘项添加到托盘, PlatformUI.getWorkbench().close()用于关闭系统。
- l trayItem.add(new Logoff())中的new Logoff()生成“用户注销”Action,并作为托盘项添加到托盘。
- 2.修改ApplicationWorkbenchWindowAdvisor类l 首先定义一个HookSysTray 对象:
- private HookSysTray hookSysTray;
- 添加用于创建hookSysTray对象的createSystemTray()方法:
- private void createSystemTray() {
- hookSysTray = new HookSysTray();
- hookSysTray.createSysTray(getWindowConfigurer().getWindow());
- }
- 修改postWindowOpen()方法,在该方法中调用createSystemTray()创建系统托盘:
- public void postWindowOpen() {
-
- Shell shell = getWindowConfigurer().getWindow().getShell();
- Rectangle screenSize = Display.getDefault().getClientArea();
- Rectangle frameSize = shell.getBounds();
- shell.setLocation((screenSize.width - frameSize.width) / 2,
- (screenSize.height - frameSize.height) / 2);
- createSystemTray();
- }
- 改写preWindowShellClose()方法,防止关闭程序时关闭托盘:
- public boolean preWindowShellClose() {
- hookSysTray.windowMinimized(getWindowConfigurer().getWindow().getShell());
- return false;
- }
- 退出时释放资源:
- public void dispose() {
- hookSysTray.Dispose();
- }
- 图片的缓存处理创建图片是一项比较消耗系统资源的工作。众所周知,图片的使用原则是谁创建谁销毁以防止内存泄漏。系统使用图片的地方较多,因此应该统一高效地管理。将图片缓存起来,就可以在需要用到图片时直接从缓存中调用,而不是重新加载。下面是实现图片缓存处理的具体过程。
- 1.创建缓存CacheImage类CacheImage类负责创建、缓存、销毁图片等工作,以后凡是系统中需要使用图片的地方都由该类负责处理,代码如下。
- cn.edu.jfcs.sys / CacheImage.java
- import …
- public class CacheImage {
- private final Map<String, Image> imageMap = new HashMap<String, Image>();
- private static CacheImage INSTANCE=new CacheImage();
- private CacheImage() {}
-
- public static CacheImage getINSTANCE(){
- return INSTANCE;
- }
-
- public Image getImage(String applicationID,String imageName) {
- if (imageName == null)
- return null;
- Image image = (Image) imageMap.get(imageName);
- if (image == null) {
- image =AbstractUIPlugin.imageDescriptorFromPlugin(
- applicationID,imageName).createImage();
- imageMap.put(imageName, image);
- }
- return image;
- }
-
- public void dispose() {
-
- Iterator iterator = imageMap.values().iterator();
- while (iterator.hasNext())
- ((Image) iterator.next()).dispose();
- imageMap.clear();
- }
- }
- 2.修改HookSysTray类
- 去掉private Image trayImage语句。
- 修改初始化托盘项目initTrayItem()方法:
- private TrayItem initTrayItem(IWorkbenchWindow window) {
- final Tray tray = window.getShell().getDisplay().getSystemTray();
- if (tray == null) return null;
- trayItem = new TrayItem(tray, SWT.NONE);
- trayItem.setImage(CacheImage.getINSTANCE().getImage(
- IAppConstants.APPLICATION_ID, IImageKey.WINDOW_IMAGE));
- trayItem.setToolTipText(IAppConstants.APPLICATION_TITLE);
- return trayItem;
- }
- 3.修改ApplicationWorkbenchWindowAdvisor类的dispose()方法public void dispose() {
- hookSysTray.Dispose();
- CacheImage.getINSTANCE().dispose();
- }
- 图像处理也可以采用图像描述符ImageDescriptor。ImageDescriptor的好处是不需要用户干预,由Java垃圾收集器自动释放和回收。前面创建Action时使用的就是图像描述符。当然,使用图像注册表ImageRegistry也是一个好方法,可以编写一个专门类利用图像注册表进行图像缓存管理。
- 定时自动显示托盘气泡提示文本气泡提示文本是一种非常友好的向用户展示信息的方式,很多软件的托盘图标都带有气泡提示文本,经常可见的气泡提示文本是向电脑插入U盘时显示的提示文本,其他还有瑞星杀毒软件、卡巴斯基、WindowsXP安全中心等等。Eclipse从3.2版本开始也支持气泡提示文本。
- 添加气泡提示文本其实非常简单,设置托盘项目trayItem的ToolTip就可以了。下面来实现一个能够每隔30分钟自动显示气泡提示文本的系统托盘,这需要修改初始化托盘项目文字和图标的initTrayItem()方法,黑体为新加代码。
- private TrayItem initTrayItem(final IWorkbenchWindow window) {
- ……
- trayItem.setImage(CacheImage.getINSTANCE().getImage(
- IAppConstants.APPLICATION_ID, IImageKey.WINDOW_IMAGE));
-
- Timer timer = new Timer();
- timer.schedule(new TimerTask() {
- public void run() {
- window.getShell().getDisplay().asyncExec(new Runnable() {
- public void run() {
- ToolTip tip = new ToolTip(window.getShell(),
- SWT.BALLOON | SWT.ICON_INFORMATION);
- tip.setAutoHide(true);
-
- tip.setMessage(IAppConstants.APPLICATION_TITLE);
- tip.setText("欢迎使用");
- trayItem.setToolTip(tip);
- tip.setVisible(true);
- }
- });
- }
- }, 0, 30 * 60 * 1000);
- return trayItem;
- }
- 程序说明:
- Timer是一个线程安全的定时器,这里设置的时间间隔为30分钟。为了调试程序时观察效果,可以设置得小一些,例如30秒(30×1000),调试好后再设置时间长些。
- SWT.BALLOON设置提示文本为气泡式样,SWT.ICON_INFORMATION则表示带一个信息图标。
- 注意在Timer线程内部进行改变UI界面的操作时,需要使用window.getShell(). getDisplay().asyncExec()。