【swing】如何实现:左键点击任意地方,托盘菜单自动隐藏

rt

 1.swing自带点击事件。只能在java创建的程序/界面上触发,点击其他地方(如桌面),无法触发点击事件。

2.JIntellitype全局热键注册。没有发现有鼠标左键的热键。

 还有什么方法实现这个正常托盘程序应有的功能。。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.UnsupportedEncodingException;

public class MainFrame extends JFrame implements ActionListener {
	private static final String titleName = "test";
	private static final long serialVersionUID = -7078030311369039390L;
	private JMenu menu;
	private JMenuBar jmenuBar;
	//菜单项目
	private String[] jmItemName = {"Hidden", "Exit"};
	public static JTextArea jTextArea;
	public static JPopupMenu popupMenu;
	public static JDialog dialog;
	public static MainFrame mainFrame;
	private MainFrame() throws UnsupportedEncodingException {
		//主标题名
		super(titleName);
		dialog = new JDialog();
		dialog.setUndecorated(true);
		dialog.addWindowFocusListener(new WindowFocusListener() {
			
			@Override
			public void windowLostFocus(WindowEvent e) {
				System.out.println("设置隐藏");
				dialog.setVisible(false);
			}
			
			@Override
			public void windowGainedFocus(WindowEvent e) {
			}
		});
		//初始化菜单栏
		initJmenuBar();
		//设置窗口大小
		this.setSize(500, 400);
		//添加菜单栏
		this.setJMenuBar(jmenuBar);
		//窗口居中
		this.setLocationRelativeTo(null);
		//设置窗口图标
		//        this.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("icon.jpg")));
		//全局设置TextArea(文本域) 不可编辑时,文字颜色黑色(默认灰色)
		UIManager.put("TextArea.inactiveForeground", new Color(0, 0, 0));
		//创建文本域
		jTextArea = new JTextArea();
		//文本域,不可编辑
		jTextArea.setEnabled(false);
		//创建滚动窗格,并添加文本域
		JScrollPane scroll = new JScrollPane(jTextArea);
		//添加滚动窗格作为主体控件
		add(scroll);
		//系统托盘
		systemTray();
		//初始化完毕,显示界面
		this.setVisible(true);
		//测试窗格滚动条
		for (int i = 0; i < 50; i++) {
			//            stringBuilder.append(i).append("\r\n");
			jTextArea.append(i + "  " + jTextArea.getLineCount());
			jTextArea.append("测试滚动条1,测试滚动条2,测试滚动条3,测试滚动条4,测试滚动条5,测试滚动条6,测试滚动条7,测试滚动条8,测试滚动条9,测试滚动条10");
			//            txaDisplay.append("\r\n");
			jTextArea.append(System.getProperty("line.separator"));
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		mainFrame = this;
	}
	/**
	 * 初始化界面
	 */
	private void initJmenuBar() {
		//创建主项
		menu = new JMenu("System");
		for (String s : jmItemName) {
			//创建子项
			JMenuItem menuItem = new JMenuItem(s);
			//设置子项点击事件
			menuItem.addActionListener(this);
			//添加子项到主项
			menu.add(menuItem);
		}
		//创建菜单栏
		this.jmenuBar = new JMenuBar();
		//添加主项到菜单栏
		this.jmenuBar.add(menu);
	}
	/**
	 * @param e
	 * @return void
	 * @Description 点击效果
	 * @Date 13:20 2021/04/20
	 **/
	@Override
	public void actionPerformed(ActionEvent e) {
		String actions = e.getActionCommand();
		if ("Hidden".equals(actions)) {
			//隐藏窗口
			this.setVisible(false);
		} else if ("Exit".equals(actions)) {
			//退出程序
			System.exit(0);
		}
	}
	/**
	 * 系统托盘图标处理.
	 */
	private void systemTray() {
		//判断系统是否支持托盘功能.
		if (SystemTray.isSupported()) {
			//创建图片对象,指定图标地址
			ImageIcon icon = new ImageIcon(getClass().getClassLoader().getResource("icon.png"));
			//创建弹出菜单对象
			popupMenu = new JPopupMenu();
			//创建子项,显示
			JMenuItem itemShow = new JMenuItem("Show");
			//创建子项,退出
			JMenuItem itemExit = new JMenuItem("Exit");
			//添加子项到弹出菜单
			popupMenu.add(itemShow);
			popupMenu.add(itemExit);

			//创建托盘图标,设置图片,设置标题名
			TrayIcon trayIcon = new TrayIcon(icon.getImage(), titleName);
			//获取系统托盘
			SystemTray sysTray = SystemTray.getSystemTray();
			try {
				//系统托盘,添加托盘图标
				sysTray.add(trayIcon);
			} catch (AWTException ignored) {
			}
			
			//添加鼠标点击事件
			trayIcon.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseReleased(MouseEvent e) {
					//右键点击
					if (e.isPopupTrigger()) {
						//设置窗口坐标为鼠标点击位置
						dialog.setLocation(e.getX(), e.getY());
//						popupMenu.setLocation(e.getX(), e.getY());
						//调用弹出菜单
						popupMenu.setInvoker(popupMenu);
						//显示弹出菜单
						dialog.setVisible(true);
						dialog.setFocusable(true);
						popupMenu.show(dialog, 0, 0);
						//TODO:添加热键
					}
					//左键双击
					if (e.getClickCount() == 2) {
						//显示主界面
						setVisible(true);
						//隐藏弹出菜单
						popupMenu.setVisible(false);
					}
				}
				@Override
				public void mouseExited(MouseEvent e) {
					//鼠标移出事件
					System.out.println("trayIcon mouseExited");
					//隐藏菜单
					popupMenu.setVisible(false);
				}
			});

			//子项show,添加点击事件
			itemShow.addActionListener(e -> {
				//显示主界面
				setVisible(true);
			});
			//子项exit,添加点击事件
			itemExit.addActionListener(e -> {
				//删除托盘图标
				sysTray.remove(trayIcon);
				//结束程序
				dispose();
				//退出程序
				System.exit(0);
			});
			//            trayIcon.addMouseListener(new MouseAdapter() {
			//                public void mouseClicked(MouseEvent e) {
			//                    //如果点击右键 显示子菜单
			//                    if (e.getButton() == MouseEvent.BUTTON3) {
			//                        //获取相对于窗口的逻辑位置
			//                        Point p = e.getPoint();
			//                        popupMenu.show(e.getComponent(), p.x, p.y);
			//                    }
			//                    //否则不显示子菜单
			//                    else {
			//                        popupMenu.setVisible(false);
			//                    }
			//                }
			//            });
		}
	}
	/**
	 * 主方法
	 *
	 * @param args sdf
	 */
	public static void main(String[] args) throws UnsupportedEncodingException {
		new MainFrame();
		System.out.println("创建完毕");
		//        for (int i = 0; i < 50; i++) {
		////            stringBuilder.append(i).append("\r\n");
		//            jTextArea.append(i + "  " + jTextArea.getLineCount());
		//            jTextArea.append("(2021/04/15 03:00:00) Doing housekeeping... (Backup file before 2021/04/15 02:00:00)11111111111");
		////            txaDisplay.append("\r\n");
		//            jTextArea.append(System.getProperty("line.separator"));
		//            try {
		//                Thread.sleep(200);
		//            } catch (InterruptedException e) {
		//                e.printStackTrace();
		//            }
		//        }
	}
}

 

应该是调用windows的系统监听吧,不知道有没有现成的jar包可以用

可以试试失焦事件

addWindowFocusListener

窗体失去焦点时自动隐藏

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class MainForm extends JFrame implements WindowListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
    public MainForm() {
         this.setTitle("窗体事件");
         setSize(600, 400);
         setResizable(false);
         setLocationRelativeTo(null);
 
         this.addWindowListener(this);
     }
	
	public static void main(String[] args) {
		 JFrame frame = new MainForm();
         frame.setVisible(true);
	}

        @Override
	public void windowDeactivated(WindowEvent e) {
		JOptionPane.showMessageDialog(null, "已失去焦点且处于非激活状态");
		
	}

	@Override
	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosing(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	

}
package com.demo;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.UnsupportedEncodingException;


public class MainFrame extends JFrame implements ActionListener {

    private static final String titleName = "test";

    private static final long serialVersionUID = -7078030311369039390L;
    private JMenu menu;
    private JMenuBar jmenuBar;
    //菜单项目
    private String[] jmItemName = {"Hidden", "Exit"};

    public static JTextArea jTextArea;
    public static JPopupMenu popupMenu;

    private MainFrame() throws UnsupportedEncodingException {
        //主标题名
        super(titleName);

        //初始化菜单栏
        initJmenuBar();

        //设置窗口大小
        this.setSize(500, 400);
        //添加菜单栏
        this.setJMenuBar(jmenuBar);
        //窗口居中
        this.setLocationRelativeTo(null);
        //设置窗口图标
        this.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("icon.jpg")));

        //全局设置TextArea(文本域) 不可编辑时,文字颜色黑色(默认灰色)
        UIManager.put("TextArea.inactiveForeground", new Color(0, 0, 0));

        //创建文本域
        jTextArea = new JTextArea();
        //文本域,不可编辑
        jTextArea.setEnabled(false);

        //创建滚动窗格,并添加文本域
        JScrollPane scroll = new JScrollPane(jTextArea);
        //添加滚动窗格作为主体控件
        add(scroll);

        //系统托盘
        systemTray();

        this.addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {
                System.out.println("windowOpened");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("windowClosing");
            }

            @Override
            public void windowClosed(WindowEvent e) {
                System.out.println("windowClosed");
            }

            @Override
            public void windowIconified(WindowEvent e) {
                System.out.println("windowIconified");
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
                System.out.println("windowDeiconified");
            }

            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                System.out.println("windowDeactivated");
            }
        });

        //初始化完毕,显示界面
        this.setVisible(true);

        //测试窗格滚动条
        for (int i = 0; i < 50; i++) {
//            stringBuilder.append(i).append("\r\n");
            jTextArea.append(i + "  " + jTextArea.getLineCount());
            jTextArea.append("测试滚动条1,测试滚动条2,测试滚动条3,测试滚动条4,测试滚动条5,测试滚动条6,测试滚动条7,测试滚动条8,测试滚动条9,测试滚动条10");
//            txaDisplay.append("\r\n");
            jTextArea.append(System.getProperty("line.separator"));
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 初始化界面
     */
    private void initJmenuBar() {
        //创建主项
        menu = new JMenu("System");
        for (String s : jmItemName) {
            //创建子项
            JMenuItem menuItem = new JMenuItem(s);
            //设置子项点击事件
            menuItem.addActionListener(this);
            //添加子项到主项
            menu.add(menuItem);
        }
        //创建菜单栏
        this.jmenuBar = new JMenuBar();
        //添加主项到菜单栏
        this.jmenuBar.add(menu);
    }

    /**
     * @param e
     * @return void
     * @Description 点击效果
     * @Date 13:20 2021/04/20
     **/
    @Override
    public void actionPerformed(ActionEvent e) {
        String actions = e.getActionCommand();
        if ("Hidden".equals(actions)) {
            //隐藏窗口
            this.setVisible(false);
        } else if ("Exit".equals(actions)) {
            //退出程序
            System.exit(0);
        }

    }

    /**
     * 系统托盘图标处理.
     */
    private void systemTray() {
        //判断系统是否支持托盘功能.
        if (SystemTray.isSupported()) {
            //创建图片对象,指定图标地址
            ImageIcon icon = new ImageIcon(getClass().getClassLoader().getResource("icon.jpg"));

            //创建弹出菜单对象
            popupMenu = new JPopupMenu();
            //创建子项,显示
            JMenuItem itemShow = new JMenuItem("Show");
            //创建子项,退出
            JMenuItem itemExit = new JMenuItem("Exit");

            //添加子项到弹出菜单
            popupMenu.add(itemShow);
            popupMenu.add(itemExit);


            //创建托盘图标,设置图片,设置标题名
            TrayIcon trayIcon = new TrayIcon(icon.getImage(), titleName);
            //获取系统托盘
            SystemTray sysTray = SystemTray.getSystemTray();
            try {
                //系统托盘,添加托盘图标
                sysTray.add(trayIcon);
            } catch (AWTException ignored) {
            }

            //添加鼠标点击事件
            trayIcon.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseReleased(MouseEvent e) {
                    //右键点击
                    if (e.isPopupTrigger()) {
                        //设置窗口坐标为鼠标点击位置
                        popupMenu.setLocation(e.getX(), e.getY());
                        //调用弹出菜单
                        popupMenu.setInvoker(popupMenu);
                        //显示弹出菜单
                        popupMenu.setVisible(true);
                        //TODO:添加热键
                    }
                    //左键双击
                    if (e.getClickCount() == 2) {
                        //显示主界面
                        setVisible(true);
                        //隐藏弹出菜单
                        popupMenu.setVisible(false);
                    }
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    //鼠标移出事件
                    System.out.println("trayIcon mouseExited");
                    //隐藏菜单
                    popupMenu.setVisible(false);
                }
            });


            //子项show,添加点击事件
            itemShow.addActionListener(e -> {
                //显示主界面
                setVisible(true);
            });

            //子项exit,添加点击事件
            itemExit.addActionListener(e -> {
                //删除托盘图标
                sysTray.remove(trayIcon);
                //结束程序
                dispose();
                //退出程序
                System.exit(0);
            });

//            trayIcon.addMouseListener(new MouseAdapter() {
//                public void mouseClicked(MouseEvent e) {
//                    //如果点击右键 显示子菜单
//                    if (e.getButton() == MouseEvent.BUTTON3) {
//                        //获取相对于窗口的逻辑位置
//                        Point p = e.getPoint();
//                        popupMenu.show(e.getComponent(), p.x, p.y);
//                    }
//                    //否则不显示子菜单
//                    else {
//                        popupMenu.setVisible(false);
//                    }
//                }
//            });

        }
    }

    /**
     * 主方法
     *
     * @param args sdf
     */
    public static void main(String[] args) throws UnsupportedEncodingException {
        new MainFrame();
        System.out.println("创建完毕");
//        for (int i = 0; i < 50; i++) {
////            stringBuilder.append(i).append("\r\n");
//            jTextArea.append(i + "  " + jTextArea.getLineCount());
//            jTextArea.append("测试滚动条1,测试滚动条2,测试滚动条3,测试滚动条4,测试滚动条5,测试滚动条6,测试滚动条7,测试滚动条8,测试滚动条9,测试滚动条10");
////            txaDisplay.append("\r\n");
//            jTextArea.append(System.getProperty("line.separator"));
//            try {
//                Thread.sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
    }
}

 

这是测试代码,需要在resources放入上面的 icon.jpg 才能运行