【JavaFx实现系统托盘,去重AWT托盘乱码】
- 说明
Javafx实现系统托盘,默认使用的是awt的组件, 但是源码是utf-8,程序运行的时候有中文菜单就产生乱码,即使转码也无效,参考资料说PopupMenu只支持英文,TNND,想了半天缺点怎么能行啊,就查找资料最后找到可以使用swing的组件替代awt实现托盘效果,还不用-Dfile.encoding=gbk,下面让我们来一起看看吧. - swing 系统托盘源码[修正错误]
package com.liangchao.csp.wins;
import com.liangchao.csp.resource.R;
import lombok.SneakyThrows;
import org.springframework.core.io.ClassPathResource;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URL;
/**
* JAVA Swing 系统托盘菜单实现 JPopupMenu + JDialog 取代 PopupMenu
*
* @author Administrator
* @version 1.0
* @class cloud-service-platform--LCH
* @description:
* @date 2022/9/9 8:28
*/
public class JPopupMenuTest {
public static void main(String[] args) throws IOException {
System.setProperty("file.encoding","UTF-8");
//应用主窗口
JFrame frame = new JFrame();
//使用JDialog 作为JPopupMenu载体
JDialog popWindow = new JDialog();
popWindow.setUndecorated(true);
//popWindow作为JPopupMenu载体不需要多大的size
popWindow.setSize(1, 1);
//创建JPopupMenu
//重写firePopupMenuWillBecomeInvisible
//消失后将绑定的组件一起消失
JPopupMenu pop = new JPopupMenu() {
@Override
public void firePopupMenuWillBecomeInvisible() {
popWindow.setVisible(false);
System.out.println("JPopupMenu不可见时绑定载体组件popWindow也不可见");
}
};
pop.setSize(100, 30);
//添加菜单选项
JMenuItem exit = new JMenuItem("退出");
pop.add(exit);
exit.addActionListener(e -> {
System.out.println("点击了退出选项");
System.exit(0);
});
//创建托盘图标
//加载系统托盘图标
ClassPathResource trayClassPathResource = new ClassPathResource(R.ICON_3D_EFFECT_BOX);
URL url = trayClassPathResource.getURL();
//使用awt的组件制作系统托盘按钮
java.awt.Image image = Toolkit.getDefaultToolkit().getImage(url);
TrayIcon trayIcon = new TrayIcon(image);
trayIcon.setImageAutoSize(true);
//给托盘图标添加鼠标监听
trayIcon.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
//左键点击
if (e.getButton() == 1) {
//显示窗口
frame.setVisible(true);
} else if (e.getButton() == 3 && e.isPopupTrigger()) {
//右键点击弹出JPopupMenu绑定的载体以及JPopupMenu
popWindow.setLocation(e.getX() + 5, e.getY() - 5 - 30);
popWindow.setVisible(true);
pop.show(popWindow, 0, 0);
}
}
});
//取消默认关闭事件,自定义使其放在右下角的系统托盘
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@SneakyThrows
@Override
public void windowClosing(WindowEvent e) {
// 应用主窗口不可见 != 应用退出
frame.setVisible(false);
// 将托盘图标添加到系统的托盘实例中
SystemTray tray = SystemTray.getSystemTray();
for (TrayIcon temp : tray.getTrayIcons()) {
if (temp.equals(trayIcon)) {
return;
}
}
tray.add(trayIcon);
}
});
frame.setBounds(500, 500, 200, 200);
frame.setVisible(true);
}
}
- JavaFx源码实现
private TrayIcon trayIcon;// 系统托盘组件
/**
* 系统托盘
*/
public void systemTray(Stage stage) {
try {
if (trayIcon == null) {
//设置为false时点击关闭按钮程序不会退出
Platform.setImplicitExit(false);
//使用JDialog 作为JPopupMenu载体
JDialog popWindow = new JDialog();
popWindow.setUndecorated(true);
//popWindow作为JPopupMenu载体不需要多大的size
popWindow.setSize(1, 1);
//加载系统托盘图标
// ClassPathResource trayClassPathResource = new ClassPathResource(R.ICON_LAYERS_TO_TOP);
// URL url = trayClassPathResource.getURL();
//使用awt的组件制作系统托盘按钮
java.awt.Image image = Toolkit.getDefaultToolkit().getImage(new ClassPathResource(R.ICON_LAYERS_TO_TOP).getURL());
JPopupMenu trayMenu = new JPopupMenu() {
@Override
protected void firePopupMenuWillBecomeInvisible() {
Platform.runLater(() -> {
stage.show();
SystemTray.getSystemTray().remove(trayIcon);
trayIcon = null;
});
}
};
JMenuItem show = new JMenuItem("Show:显示", new ImageIcon(new ClassPathResource(R.ICON_LAYERS_TO_TOP).getURL()));// "Show:显示"
//绑定系统托盘事件
show.addActionListener(actionListener -> {
Platform.runLater(() -> stage.show());
});
JMenuItem exit = new JMenuItem("Exit:退出", new ImageIcon(new ClassPathResource(R.ICON_EXIT).getURL()));//"Exit:退出"
exit.addActionListener(actionListener -> {
shutdown();
});
JMenuItem exitTray = new JMenuItem("ExitTray:退出托盘", new ImageIcon(new ClassPathResource(R.ICON_ARROW_TOP).getURL()));//"ExitTray:退出托盘"
exitTray.addActionListener(actionListener -> {
Platform.runLater(() -> {
stage.show();
SystemTray.getSystemTray().remove(trayIcon);
trayIcon = null;
});
});
trayMenu.add(show);
trayMenu.add(exitTray);
trayMenu.add(exit);
//加载系统托盘组件
trayIcon = new TrayIcon(image, "系统");
//系统托盘图片自适应
trayIcon.setImageAutoSize(true);
//给托盘图标添加鼠标监听
trayIcon.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(java.awt.event.MouseEvent e) {
//左键点击
if (e.getButton() == 1) {
//显示窗口
Platform.runLater(() -> stage.show());
} else if (e.getButton() == 3 && e.isPopupTrigger()) {
//右键点击弹出JPopupMenu绑定的载体以及JPopupMenu
popWindow.setLocation(e.getX() + 5, e.getY() - 5 - 30);
popWindow.setVisible(true);
trayMenu.show(popWindow, 0, 0);
}
}
});
//将系统托盘组件加载到系统托盘中
SystemTray.getSystemTray().add(trayIcon);
}
stage.hide();
} catch (Exception e) {
e.printStackTrace();
}
}