钟爱有嘉 2021-04-26 17:18 采纳率: 58.3%
浏览 190
已采纳

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

rt

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

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

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

  • 写回答

5条回答 默认 最新

  • Dan淡淡的心 2021-04-27 14:04
    关注
    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();
    		//            }
    		//        }
    	}
    }
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么