Java 动态更新工具提示以显示计时器

Java 动态更新工具提示以显示计时器,java,swing,icons,tooltip,tray,Java,Swing,Icons,Tooltip,Tray,我有一个应用程序,当它被最小化时会进入系统托盘。我需要显示一个带有计时器的工具提示。一切正常,但我无法在每次显示工具提示时刷新工具提示。我可以用其他方式刷新它吗,除了制作假鼠标事件并处理它来欺骗工具提示,比如,或者这是唯一的方法 upd: 我用来设置工具提示的代码 TrayIcon trayIcon; SystemTray tray; tray=SystemTray.getSystemTray(); trayIcon=new TrayIcon(image, "tooltipText"); tra

我有一个应用程序,当它被最小化时会进入系统托盘。我需要显示一个带有计时器的工具提示。一切正常,但我无法在每次显示工具提示时刷新工具提示。我可以用其他方式刷新它吗,除了制作假鼠标事件并处理它来欺骗工具提示,比如,或者这是唯一的方法

upd:

我用来设置工具提示的代码

TrayIcon trayIcon;
SystemTray tray;
tray=SystemTray.getSystemTray();
trayIcon=new TrayIcon(image, "tooltipText");
tray.add(trayIcon);
这一个正在更新工具提示

MyClass.trayIcon.setToolTip();

TrayIcon
有点问题,因为它不像其他Java AWT/Swing组件那样是
组件。我已经找到了解决方法,但它与工具提示并不完全相同
TrayIcon
具有
displayMessage
方法,可以用来代替工具提示。我已经尝试使其行为类似于工具提示(悬停时显示),但并非所有鼠标事件都受支持,所以消息必须始终显示,或单击图标。另外,我对在其他操作系统上实现消息显示也有一些担忧。我仅在MS Windows XP SP3上对其进行了测试,结果如下(每1s更新一次):

以下是可运行的示例(您需要image.jpeg才能运行):


我认为,对于基于工具提示的容器来说,不是更容易的方法,因为另一种方法可能是布局JLabel,那么一切都有可能(如果不是被Thread.sleep阻止的话)JComponent有
createToolTip()
方法。它只是创建了新的JToolkit(请参见此处),也许你们可以对它进行子类化并调用它的重绘,或者它的父组件?@Piro但它不会在显示时更新工具提示,你们是否需要它的行为完全像工具提示一样(只在鼠标悬停时显示)?@Piro应用程序在托盘中时,它应该等待某个事件。还有其他办法吗?
import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.swing.Timer;


public class TestTray {
    final ActionListener menuItemCloseAction = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    };
    final MenuItem menuItemClose = new MenuItem("Close");
    final PopupMenu menu = new PopupMenu();
    final Image image;
    {
        Image tmp = null; 
        try {
            tmp = ImageIO.read(TestTray.class.getResourceAsStream("image.jpeg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        image = tmp;
    }
    final TrayIcon trayIcon = new TrayIcon(image,null,menu);
    final SystemTray tray = SystemTray.getSystemTray();
    final DateFormat dateFormat = new SimpleDateFormat("HH:MM:ss");
    final ActionListener timerAction = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            String msg = "Time is: "+ dateFormat.format(new Date());
            //trayIcon.setToolTip(msg);
            trayIcon.displayMessage("", msg, MessageType.NONE);
        }
    };

    final Timer timer = new Timer(100, timerAction);
    {
        menu.add(menuItemClose);
        menuItemClose.addActionListener(menuItemCloseAction);
        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            e.printStackTrace();
        }
        timer.start();
    }

    public static void main(String[] args) {
        new TestTray();
    }
}