以前在做系统托盘功能时,基本都是使用开源的
trayicon实现的,因为J2SE中没有提供这样的功能。但是从J2SE6开始,已经支持了。在java.awt中增加了俩个类,一个是SystemTray,另一个是TrayIcon。
每个java应用程序中,都会有一个缺省的SystemTray实例,可以通过
SystemTray.getSystemTray()方法得到SystemTray实例。而TrayIcon才是真正的系统托盘内容,也就是说,TrayIcon是通过SystemTray才添加到系统托盘中的。系统托盘中的其他内容,比如菜单、图片、提示能都是通过TrayIcon封装的。
添加一个系统托盘,可以这样调用:
SystemTray tray = SystemTray.getSystemTray();
tray.add(trayIcon);
而删除一个系统托盘,就可以这样:
SystemTray.getSystemTray().remove(trayIcon);
下面给出一个基于JFrame对应用界面程序实现最小化时隐藏到系统托盘的功能:
import java.awt.BorderLayout;
import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import java.awt.event.*; import java.awt.*;
public class SysTrayFrame extends JFrame { private TrayIcon trayIcon; BorderLayout borderLayout1 = new BorderLayout(); JPanel root = new JPanel(); JButton exit = new JButton();
public SysTrayFrame() { try { jbInit(); pack(); this.initTrayIcon(); } catch (Exception exception) { exception.printStackTrace(); } }
private void jbInit() throws Exception { this.setDefaultCloseOperation (WindowConstants.HIDE_ON_CLOSE); this.addWindowListener(new WindowAdapter(){ //捕获窗口关闭事件 public void windowClosing(WindowEvent e){ if(SystemTray.isSupported()){ setVisible(false); minimizeToTray(); } else{ System.exit(0); } } //捕获窗口最小化事件 public void windowIconified(WindowEvent e){ if(SystemTray.isSupported()){ setVisible(false); minimizeToTray(); } else{ System.exit(0); } } }); getContentPane().setLayout(borderLayout1); exit.setText("exit"); exit.addActionListener(new SysTrayFrame_exit_actionAdapter(this)); this.getContentPane().add(root, java.awt.BorderLayout.CENTER); root.add(exit); } private void initTrayIcon(){ Image image = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("Duke16.gif")); PopupMenu popup = new PopupMenu(); MenuItem exitItem = new MenuItem("Show"); ActionListener listener = new ActionListener(){ public void actionPerformed(ActionEvent e) { setVisible(true); setExtendedState(Frame.NORMAL); SystemTray.getSystemTray().remove(trayIcon); } }; exitItem.addActionListener(listener); popup.add(exitItem); //根据image、提示、菜单创建TrayIcon this.trayIcon = new TrayIcon(image,"MyTray",popup); //给TrayIcon添加事件监听器 this.trayIcon.addActionListener(listener); }
public void minimizeToTray(){ SystemTray tray = SystemTray.getSystemTray(); try { tray.add(this.trayIcon); } catch (AWTException ex) { ex.printStackTrace(); } }
public static void main(String[] args) { SysTrayFrame systrayframe = new SysTrayFrame(); systrayframe.setTitle("MyTray"); systrayframe.setVisible(true); }
public void exit_actionPerformed(ActionEvent e) { System.exit(0); } }
class SysTrayFrame_exit_actionAdapter implements ActionListener { private SysTrayFrame adaptee; SysTrayFrame_exit_actionAdapter(SysTrayFrame adaptee) { this.adaptee = adaptee; }
public void actionPerformed(ActionEvent e) { adaptee.exit_actionPerformed(e); } }
上面的示例中,关闭窗口和最小化窗口都隐藏应用到系统托盘,只有点击exit按钮才真正退出。当然,比较好的做饭时,在点击最小化时隐藏到系统托盘,点击关闭时提示用户,是要隐藏到系统托盘还是真的要退出,这样就更人性化。
其中的关键代码已经标注为蓝色,其他的都是些辅助。
如果要实现更高级点的功能,比如根据程序运行状态改变系统托盘图标、提示等,就需要通过给SystemTray添加属性变化监听器来实现,即addPropertyChangeListene r接口。通过在addPropertyChangeListene r接口中 propertyChange方法中监听指定的属性值,再更具需要修改TrayIcon的内容即可实现动态监听和变化的功能。
本文转自:http://blog.sina.com.cn/s/blog_46e73e77010089w1.html (作者注)