Java swing 仿QQ实现系统托盘图标(下)

接着上次更新的java swing 仿QQ实现系统托盘图标(上),现在更新下篇,主要为托盘图标的弹出菜单添加菜单项图标。

TrayIcon只能添加PopupMenu弹出菜单,而PopupMenu弹出菜单不能为菜单项(MenuItem)添加图标。

本人想到的解决方法就是自己写个MyTrayIcon类,此类继承TrayIcon,以JDialog作为弹出菜单的显示媒介。


先上效果图

Java swing 仿QQ实现系统托盘图标(下)_第1张图片



下面上MyTrayIcon的代码:

import java.awt.Dimension;
import java.awt.Image;
import java.awt.TrayIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JDialog;
import javax.swing.JPopupMenu;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

/**
 * 继承TrayIcon,以JDialog作为弹出菜单的显示媒介
 */
public class MyTrayIcon extends TrayIcon {
		
	private JDialog dialog;
	
	/**
	 * 构造方法,创建带指定图像、工具提示和弹出菜单的 MyTrayIcon
	 * @param image 显示在系统托盘的图标
	 * @param ps	鼠标移动到系统托盘图标上的提示信息
	 * @param Jmenu	弹出菜单
	 */
	public MyTrayIcon(Image image,String ps,JPopupMenu Jmenu) {
		super(image,ps);
	    	
	    //初始化JDialog
	    dialog = new JDialog();
	    dialog.setUndecorated(true);//取消窗体装饰
	    dialog.setAlwaysOnTop(true);//设置窗体始终位于上方
	        
	    //设置系统图标大小为自动调整
	    this.setImageAutoSize(true);
	        
	    //为TrayIcon设置鼠标监听器
	    this.addMouseListener(new MouseAdapter() {
	    	
	    	@Override
	        public void mouseReleased(MouseEvent e) {
	            	
	        	//鼠标右键在组件上释放时调用,显示弹出菜单
	            if (e.getButton()==MouseEvent.BUTTON3 && Jmenu != null) {
	            	
	            	//设置dialog的显示位置
	            	Dimension size = Jmenu.getPreferredSize();
	    	        dialog.setLocation(e.getX()-size.width-3, e.getY() - size.height-3);
	    	        dialog.setVisible(true);
	    	        
	    	        //显示弹出菜单Jmenu
	    	        Jmenu.show(dialog.getContentPane(), 0, 0);
	    	    }
	        }
	    });
	    
	    //为弹出菜单添加监听器
	    Jmenu.addPopupMenuListener(new PopupMenuListener() {
	    	
	    	@Override
	    	public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
	    	
	    	@Override
		    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
		    	dialog.setVisible(false);
		    }
	    	
	    	@Override
		    public void popupMenuCanceled(PopupMenuEvent e) {
		        dialog.setVisible(false);
		    }
	    });
	
	}
	
}


再更新一下原来的部分,把TrayIcon替换为MyTrayIcon,再为菜单项添加监听器


大部分内容已在上篇写了,下面给出完整代码

Demo:

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.SystemTray;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicPopupMenuUI;


public class Demo {

	public static void main(String[] args) throws Exception {
		
		//将本机系统外观设置为窗体当前外观
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		
		//初始化窗体
		JFrame frame=new JFrame("My QQ");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(500, 500);
		frame.setLocationRelativeTo(null);
		frame.setType(Window.Type.UTILITY);
		
		ImageIcon img=new ImageIcon(Demo.class.getClassLoader().getResource("res/images/logo.gif"));
		frame.setIconImage(img.getImage());
		
		//定义弹出菜单
		JPopupMenu Jmenu=new JPopupMenu();
		
		//为JPopupMenu设置UI
		Jmenu.setUI(new BasicPopupMenuUI(){
			@Override
			public void paint(Graphics g, JComponent c){
				super.paint(g, c);
				
				//画弹出菜单左侧的灰色背景
				g.setColor(new Color(236,237,238));
				g.fillRect(0, 0, 25, c.getHeight());
				
				//画弹出菜单右侧的白色背景
				g.setColor(new Color(255,255,255));
				g.fillRect(25, 0, c.getWidth()-25, c.getHeight());
			}
		});
		
		//定义弹出菜单项
		JMenuItem online = new JMenuItem("我在线上",new ImageIcon(
				Demo.class.getClassLoader().getResource("res/images/online.png")));
		JMenuItem busy = new JMenuItem("忙碌",new ImageIcon(
				Demo.class.getClassLoader().getResource("res/images/busy.png")));
		JMenuItem invisible= new JMenuItem("隐身");
		JMenuItem openmenu = new JMenuItem("打开主面板");
		JMenuItem closemenu = new JMenuItem("退出MyQQ");
		
		//添加弹出菜单项到弹出菜单
		Jmenu.add(online);
		Jmenu.add(busy);
		Jmenu.add(invisible);
		Jmenu.addSeparator();//添加分割线
		Jmenu.add(openmenu);
		Jmenu.add(closemenu);
		
		//得到当前系统托盘
		SystemTray systemtray = SystemTray.getSystemTray();
		
		//创建带指定图像、工具提示和弹出菜单的 MyTrayIcon
		MyTrayIcon trayicon=new MyTrayIcon(img.getImage(),"MyQQ",Jmenu);
		
		//将TrayIcon添加到系统托盘
		try {
			systemtray.add(trayicon); 
		} catch (AWTException e1) {
			e1.printStackTrace();
		}
		
		//设置单击击系统托盘图标显示主窗口
		trayicon.addMouseListener(new MouseAdapter(){ 
			@Override
			public void mouseClicked(MouseEvent e) {
				
				//鼠标左键点击,设置窗体状态,正常显示
				if(e.getButton()==MouseEvent.BUTTON1){
					frame.setExtendedState(JFrame.NORMAL);
					frame.setVisible(true);
				}
			}
		});
		
		//定义ActionListener监听器
		ActionListener MenuListen = new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
					           
				if (e.getActionCommand().equals("退出MyQQ")){
					 
					systemtray.remove(trayicon); 
					System.exit(0);
				}
				else if(e.getActionCommand().equals("打开主面板")){
					frame.setExtendedState(JFrame.NORMAL);
					frame.setVisible(true);
				}
					   
		}};
		
		//为弹出菜单项添加监听器
		openmenu.addActionListener(MenuListen);
		closemenu.addActionListener(MenuListen);
		
		frame.setVisible(true);
		
	}
	
}

好了,java swing 仿QQ实现系统托盘图标就到此为止。如果该博文对您有帮助,点个赞呗


另外还有个困扰,就是当鼠标一直停在弹出菜单时系统托盘会隐藏。如果想实现鼠标放在系统托盘弹出菜单上时系统托盘不隐藏怎么实现,望大佬们给点建议!

你可能感兴趣的:(java,swing,仿写QQ)