如何在Java中正确使用SystemTray?

时间:2014-03-21 14:44:16

标签: java swing awt system-tray

我尝试使用java中的SystemTray实现一个小型(测试)程序。我遇到了问题并写了一个(M)WE并用http://pastebin.com/nYBkaLSy发布了它(抱歉没有做任何安全检查)。

会发生什么(在使用openJDK的Ubuntu / KDE下):

  • 程序启动,按钮可点击。 SystemTray已注册(到目前为止可以)
  • 如果我在托盘中的图像上单击(单击鼠标左键),则该按钮不再可单击。相反,它似乎被禁用了。右键单击托盘图标或框架内容(!!!)打开弹出窗口。关闭此按钮(单击任意位置)后,按钮再次激活。 (这个行为我无法解释。就我看来,我的代码不会影响到这一点)
  • 如果我点击窗口管理器的最小化按钮,框架会消失(正确)
  • 从托盘图标弹出窗口中选择show会恢复框架,框架内容可以点击(目前为止确定)。
  • 不幸的是之后弹出窗口被禁用了。我无法再次打开它,如果我再次将窗口最小化,我就无法重新启动窗口。 (我也没有在代码中看到这一点)

现在我不确定我是否错误地理解了这些原则,或者是否存在其他错误。所以请帮我澄清我的问题。

编辑: 我在这里插入了代码(有点修改)。

请注意,创建的图像只是虚拟代码。在我的实现中,我加载了一个产生相同结果的外部图像(参见注释)。因此,评论中的iconToImage()提示似乎不是问题。

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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;

public class TestTray {

    public static void main(String[] args) {
        // Create tmp image
        Image image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_RGB);
        image.getGraphics().drawOval(2, 2, 30, 30);

        // Alternative: Load PNG image
        //URL imUrl = TestTray.class.getResource("clock.png");
        //ImageIcon icon = new ImageIcon(imUrl);
        //image = icon.getImage();

        TrayIcon ti = new TrayIcon(image);
        ti.setImageAutoSize(true);
        try {
            SystemTray.getSystemTray().add(ti);
        } catch (AWTException e) {
            e.printStackTrace();
        }

        // Create JFrame and set default things
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JButton("Test-Button"));
        frame.pack();
        frame.setVisible(true);

        // Add listener to hide window in case of minimization
        frame.addWindowStateListener(new WindowStateListener() {
            @Override
            public void windowStateChanged(WindowEvent ev) {
                if(ev.getNewState() == JFrame.ICONIFIED)
                    frame.setVisible(false);
            }
        });

        // Create popup for System tray and register it
        PopupMenu popup = new PopupMenu();
        MenuItem menuItem;

        menuItem = new MenuItem("Show");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setVisible(true);
                frame.setExtendedState(JFrame.NORMAL);
            }
        });
        popup.add(menuItem);

        menuItem = new MenuItem("Exit");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                System.exit(0);
            }
        });
        popup.add(menuItem);

        ti.setPopupMenu(popup);
    }

}

0 个答案:

没有答案