суббота, 30 июня 2012 г.

Работа с системном треем (system tray) на java

Для размещения иконки в трее можно воспользоваться стандартным классом java.awt.SystemTray, который стал доступен начиная с 6-й версии java. Данный класс воплощает собой системный трей среды в которой запущена виртуальная машина java. Перед началом работы с треем необходимо обязательно проверить его доступность с помощью метода SystemTray.isSupported(), далее следует получить текущий экземпляр SystemTray методом SystemTray.getSystemTray(). Вполне логично, что класс SystemTray является синглтоном, т.е. любое java приложение может иметь только один экземпляр SystemTray.
Системный трей может содержать некоторое количество иконок. Добавление иконок в системый трей производится с использованием команды add(java.awt.TrayIcon), а удаление командой remove(java.awt.TrayIcon).
Ниже привожу пример с официального сайта Oracle, в котором демонстрируется использование системного трея

final TrayIcon trayIcon;

if (SystemTray.isSupported()) {

    SystemTray tray = SystemTray.getSystemTray();
    Image image = Toolkit.getDefaultToolkit().getImage("tray.gif");

    MouseListener mouseListener = new MouseListener() {
                
        public void mouseClicked(MouseEvent e) {
            System.out.println("Tray Icon - Mouse clicked!");                 
        }

        public void mouseEntered(MouseEvent e) {
            System.out.println("Tray Icon - Mouse entered!");                 
        }

        public void mouseExited(MouseEvent e) {
            System.out.println("Tray Icon - Mouse exited!");                 
        }

        public void mousePressed(MouseEvent e) {
            System.out.println("Tray Icon - Mouse pressed!");                 
        }

        public void mouseReleased(MouseEvent e) {
            System.out.println("Tray Icon - Mouse released!");                 
        }
    };

    ActionListener exitListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("Exiting...");
            System.exit(0);
        }
    };
            
    PopupMenu popup = new PopupMenu();
    MenuItem defaultItem = new MenuItem("Exit");
    defaultItem.addActionListener(exitListener);
    popup.add(defaultItem);

    trayIcon = new TrayIcon(image, "Tray Demo", popup);

    ActionListener actionListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            trayIcon.displayMessage("Action Event", 
                "An Action Event Has Been Performed!",
                TrayIcon.MessageType.INFO);
        }
    };
            
    trayIcon.setImageAutoSize(true);
    trayIcon.addActionListener(actionListener);
    trayIcon.addMouseListener(mouseListener);

    try {
        tray.add(trayIcon);
    } catch (AWTException e) {
        System.err.println("TrayIcon could not be added.");
    }

} else {

    //  System Tray is not supported

}

В вышеприведенном примере есть один существенный недочет - для всплывающего меню там используется тяжеловесный устарелый компонент java.awt.PopupMenu, одним из недостатков которого является невозможность установки иконок для его MenuItem'ов. Несмотря на то, что TrayIcon по умолчанию принимает в своем конструкторе только java.awt.PopupMenu, возможность использовать более продвинутый javax.swing.JPopupMenu все же существует. Необходимо добавить к TrayIcon MouseListener, который будет создавать JPopupMenu при своем срабатывании. Ниже приведен пример такой реализации.

final TrayIcon trayIcon;

        if (SystemTray.isSupported()) {

            SystemTray tray = SystemTray.getSystemTray();
            Image image = Toolkit.getDefaultToolkit().getImage("tray.gif");



            ActionListener exitListener = new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    System.out.println("Exiting...");
                    System.exit(0);
                }
            };

            final JPopupMenu popup = new JPopupMenu();
            JMenuItem defaultItem = new JMenuItem("Exit");
            defaultItem.addActionListener(exitListener);
            popup.add(defaultItem);

            trayIcon = new TrayIcon(image, "Tray Demo");

            ActionListener actionListener = new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    trayIcon.displayMessage("Action Event",
                            "An Action Event Has Been Performed!",
                            TrayIcon.MessageType.INFO);
                }
            };

            trayIcon.setImageAutoSize(true);
            trayIcon.addActionListener(actionListener);
            trayIcon.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseReleased(MouseEvent e) {
                    if (e.isPopupTrigger()) {
                        popup.setLocation(e.getX(), e.getY());
                        popup.setInvoker(popup);
                        popup.setVisible(true);
                    }
                }
            });

            try {
                tray.add(trayIcon);
            } catch (AWTException e) {
                System.err.println("TrayIcon could not be added.");
            }

        } else {
            //  System Tray is not supported
        }

7 комментариев:

  1. Спасибо, уже год читаю твой блог, каждый раз нахожу что-то новое и интересное. Где изучал язык?

    ОтветитьУдалить
    Ответы
    1. Спасибо за хорошие слова о блоге, основы языка начинал изучать в БГУИР (Белорусском Государственном Университете информатики и радиоэлектроники), затем по большей части самостоятельно, уже непосредственно в процессе написания программ и при решении возникающих задач.

      Удалить
  2. При каких-то загадочных условиях иконка из трея исчезает, может знаете как ей апдейт сделать?

    ОтветитьУдалить
    Ответы
    1. Сложно сказать в чем проблема, вполне может быть что она связана с операционной системой (есть такой "известный" глюк в Windows Xp), с проблемами подобного рода связанными с программной реализацией иконки в системном трее на java я ни разу не сталкивался.
      Проверьте установлена ли на компьютере последняя версия java, если нет - обновите её.

      Если же эта проблема связана с виндовс - при пропадании иконки, перезапустите процесс explorer.exe, иконка должна появиться.

      Удалить
  3. при потере фокуса меню JPopupMenu не пропадает

    ОтветитьУдалить
  4. можно пример полноценной программы

    ОтветитьУдалить
  5. Я тоже всё изучаю сам, с нуля. Всё пока работает, спасибо. Включу такие фишки в мою след игру.. Если никто не возражает?

    ОтветитьУдалить

Ярлыки

java (31) оптимизация (7) CPanel (5) svn (5) windows xp (5) ошибка (5) свой сервер (5) файлы и папки (5) gui (4) регулярные выражения (4) jacoco (3) redmine (3) windows (3) автоматизация (3) защита данных (3) резервное копирование (3) сервер (3) JavaScript (2) Oracle SQL (2) adsl модем (2) apache maven (2) apache tomcat (2) coverage (2) dropbox (2) excel (2) firewall (2) netbeans (2) office 2007 (2) samsung (2) system tray (системный трей) (2) xerox (2) вирусы (2) принтер (2) сериализация (2) удаленный рабочий стол (2) HTML (1) JFileChooser (1) MySQL (1) Nokia (1) Ovi (1) P660R-T1 (1) WakeOnLan (1) blogger.com (1) ctfmon.exe (1) email (1) flash память (1) ftp (1) integration testing (1) ip (1) jQuery (1) jvisualWm (1) log4j (1) look and feel (1) myBatis (1) php (1) serialVersionUID (1) skype (1) smtp (1) ssh (1) swing (1) torrents (1) unit-testing (1) unix (1) vpn (1) windows 7 (1) xStarter (1) zip (1) безопасность (1) вход в систему (1) дизайн (1) документация (1) заправка (1) интернет (1) логирование (1) мышь (1) патч (1) перенос (1) печать (1) плагины (1) почтовые сообщения (1) программирование (1) процессы (1) прошивка (1) сеть (1) сеть. ошибка (1) скрытые файлы (1) списки (1) фильтрация (1) фокус (1) часовые пояса (1) шифрование (1) экран (1)